├── cli
├── utils
│ ├── __init__.py
│ ├── keys.py
│ └── generator.py
├── requirements.txt
├── README.md
└── cli.py
├── images
└── request_flow.png
├── docs
├── images
│ ├── cognito
│ │ ├── cognito-landing.png
│ │ ├── cognito-app-client.png
│ │ ├── cognito-app-registration.png
│ │ └── cognito-domain-registration.png
│ ├── keycloak
│ │ ├── keycloak-pkce.png
│ │ ├── keycloak-access-settings.png
│ │ ├── keycloak-client-create-2.png
│ │ └── keycloak-client-create.png
│ ├── okta
│ │ ├── okta-applications.png
│ │ ├── okta-app-integration.png
│ │ ├── okta-web-app-setting.png
│ │ ├── okta-client-id-secret.png
│ │ ├── okta-group-assignments.png
│ │ └── okta-sign-in-redirect-uri.png
│ └── secretsmanager
│ │ ├── sm-kv-pair.png
│ │ ├── sm-final-key.png
│ │ ├── sm-key-name.png
│ │ ├── sm-store-secret.png
│ │ ├── sm-key-name-file.png
│ │ └── sm-create-new-secret.png
├── secretsmanager.md
├── registerapplication.md
├── keypairs.md
├── cloudfront.md
├── keycloak.md
├── baseconfiguration.md
├── cognito.md
├── okta.md
├── deploy.md
└── configuration.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── src
└── js
│ ├── package.json
│ ├── lib
│ └── log
│ │ ├── index.d.ts
│ │ └── index.js
│ ├── auth.js
│ └── package-lock.json
├── LICENSE
├── README.md
├── CONTRIBUTING.md
└── template.yaml
/cli/utils/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/cli/requirements.txt:
--------------------------------------------------------------------------------
1 | boto3
2 | click
3 | cryptography
--------------------------------------------------------------------------------
/images/request_flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/images/request_flow.png
--------------------------------------------------------------------------------
/docs/images/cognito/cognito-landing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/cognito/cognito-landing.png
--------------------------------------------------------------------------------
/docs/images/keycloak/keycloak-pkce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/keycloak/keycloak-pkce.png
--------------------------------------------------------------------------------
/docs/images/okta/okta-applications.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/okta/okta-applications.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | scripts/utils/__pycache__
2 | scripts/cloudfront_config_rendered.json
3 | scripts/encoded_cloudfront_config_rendered.json
4 | cli/utils/__pycache__/
5 |
--------------------------------------------------------------------------------
/docs/images/okta/okta-app-integration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/okta/okta-app-integration.png
--------------------------------------------------------------------------------
/docs/images/okta/okta-web-app-setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/okta/okta-web-app-setting.png
--------------------------------------------------------------------------------
/docs/images/secretsmanager/sm-kv-pair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/secretsmanager/sm-kv-pair.png
--------------------------------------------------------------------------------
/docs/images/cognito/cognito-app-client.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/cognito/cognito-app-client.png
--------------------------------------------------------------------------------
/docs/images/okta/okta-client-id-secret.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/okta/okta-client-id-secret.png
--------------------------------------------------------------------------------
/docs/images/okta/okta-group-assignments.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/okta/okta-group-assignments.png
--------------------------------------------------------------------------------
/docs/images/secretsmanager/sm-final-key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/secretsmanager/sm-final-key.png
--------------------------------------------------------------------------------
/docs/images/secretsmanager/sm-key-name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/secretsmanager/sm-key-name.png
--------------------------------------------------------------------------------
/docs/images/okta/okta-sign-in-redirect-uri.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/okta/okta-sign-in-redirect-uri.png
--------------------------------------------------------------------------------
/docs/images/secretsmanager/sm-store-secret.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/secretsmanager/sm-store-secret.png
--------------------------------------------------------------------------------
/docs/images/cognito/cognito-app-registration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/cognito/cognito-app-registration.png
--------------------------------------------------------------------------------
/docs/images/keycloak/keycloak-access-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/keycloak/keycloak-access-settings.png
--------------------------------------------------------------------------------
/docs/images/keycloak/keycloak-client-create-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/keycloak/keycloak-client-create-2.png
--------------------------------------------------------------------------------
/docs/images/keycloak/keycloak-client-create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/keycloak/keycloak-client-create.png
--------------------------------------------------------------------------------
/docs/images/secretsmanager/sm-key-name-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/secretsmanager/sm-key-name-file.png
--------------------------------------------------------------------------------
/docs/images/cognito/cognito-domain-registration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/cognito/cognito-domain-registration.png
--------------------------------------------------------------------------------
/docs/images/secretsmanager/sm-create-new-secret.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/lambdaedge-openidconnect-samples/HEAD/docs/images/secretsmanager/sm-create-new-secret.png
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4 | opensource-codeofconduct@amazon.com with any additional questions or comments.
5 |
--------------------------------------------------------------------------------
/src/js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lambdaedge-openidconnect-samples",
3 | "repository": {
4 | "type": "git",
5 | "url": "https://github.com/aws-samples/lambdaedge-openidconnect-samples"
6 | },
7 | "version": "0.1.0",
8 | "description": "private github-pages",
9 | "main": "auth.js",
10 | "author": "Matt Noyce",
11 | "license": "UNLICENSED",
12 | "scripts": {
13 | "setup": "npm install",
14 | "test": "node_modules/tape/bin/tape test/js/**/*.js",
15 | "format": "node_modules/prettier/bin-prettier.js --write src/js/**/*.js"
16 | },
17 | "dependencies": {
18 | "axios": "^1.6.2",
19 | "base64url": "^3.0.1",
20 | "cookie": "^0.3.1",
21 | "jsonwebtoken": "^9.0.0",
22 | "jwk-to-pem": "^1.2.6"
23 | },
24 | "devDependencies": {
25 | "depcheck": "^1.4.7"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/docs/secretsmanager.md:
--------------------------------------------------------------------------------
1 | ## AWS Secrets Manager Setup
2 |
3 | AWS Secrets Manager is used to store OIDC configuration information that is accessible to the created Amazon CloudFront Distribution.
4 | The secret is created outside of the SAM template in order to not enforce specific encryption at rest standards.
5 |
6 | Revisit the secret created from Step 1 of the instructions and paste in the Base64-encoded value.
7 |
8 | Here is an example of what the final configuration should look like in AWS Secrets Manager for the configuration:
9 |
10 | 
11 |
12 | **NOTE:** The Secret Value presented here is the **Base64-Encoded** JSON configuration.
13 |
14 | ### Next Step
15 |
16 | Navigate to [Navigate to Amazon CloudFront URL / Troubleshoot](cloudfront.md) for the next step.
17 |
18 |
--------------------------------------------------------------------------------
/docs/registerapplication.md:
--------------------------------------------------------------------------------
1 | # Register OIDC Application
2 |
3 | In order to move forward, please register a new application with the Identity Provider (IdP) of your choice. Please see the following instructions for some common IdP's. Your IdP should have instructions on how to set up and register an application with them.
4 |
5 | - [Amazon Cognito Application Registration](cognito.md)
6 | - [Okta Application Registration](okta.md)
7 | - [Keycloak Client Creation and Registration](keycloak.md)
8 |
9 | ## Important!
10 | Take note of the `Client ID` and `Client Secret` (Optional) values that are generated after this registration process.
11 | Also, ensure that you have added the correct `Callback URIs` to the registered Application. It should include the Amazon CloudFront distribution URL with `/_callback` appended.
12 |
13 | ### Next Step
14 |
15 | Navigate to [Generate OIDC Configuration](configuration.md) for the next step.
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 |
16 |
--------------------------------------------------------------------------------
/docs/keypairs.md:
--------------------------------------------------------------------------------
1 | # Generate Public and Private Key Pairs
2 |
3 | This solution requires public and private key pairs to be generated.
4 | There are a couple of ways to generate these keys.
5 |
6 | ## OpenSSL
7 |
8 | The first mechanism to generate the key pair is to use [OpenSSL](https://www.openssl.org/). Once you have setup OpenSSL, run the following commands:
9 |
10 | ```sh
11 | openssl genrsa -out private.pem 2048
12 | openssl rsa -in private.pem -outform PEM -pubout -out public.pem
13 | ```
14 |
15 | This will output two files:
16 | 1. `private.pem` = this is the private key.
17 | 2. `public.pem` = this is the public key.
18 |
19 | ## Configuration CLI
20 |
21 | The Configuration CLI found in the [CLI Directory](../cli/) will generate the private and public key pairs and append it to the configuration file for you.
22 |
23 | ## Programmatic Libraries
24 |
25 | There are a suite of programming languages and supporting libraries that will also be able to generate these key pairs. Search for OpenSSL libraries to generate the public and private key pairs.
--------------------------------------------------------------------------------
/docs/cloudfront.md:
--------------------------------------------------------------------------------
1 | # CloudFront Testing / Troubleshooting
2 |
3 | After all configuration and deployments have completed, navigate to the HTTPS Amazon CloudFront endpoint generated from the AWS SAM template. You should be redirected to your IdP to perform Authentication.
4 |
5 | ## Troubleshooting
6 |
7 |
8 | ### HTTP 4xx or 5xx Errors
9 |
10 | If you encounter an HTTP 4xx or HTTP 5xx error, trying opening up a new browser or browsing in private mode. Sometimes there may be cached configurations that are causing the problems.
11 |
12 | ### Check IdP Configurations
13 |
14 | If there are issues, ensure that all IdP configurations are set up correctly, including the Callback URIs.
15 |
16 | ### AWS Secrets Manager Configuration
17 |
18 | Ensure that the correct AWS Secrets Manager Secret name in use which is "cloudfront/DISTRIBUTION_ID" Also, ensure that the Key-Value pair is set up correctly in AWS Secrets Manager including a Base64-encoded value that is the JSON configuration.
19 |
20 |
21 | ### AWS Secrets Manager Customer-Managed KMS Key Policy
22 |
23 | If using an AWS Customer-Managed KMS Key, ensure that the Lambda@Edge Function Execution role is in the list of KMS key users.
24 |
25 |
--------------------------------------------------------------------------------
/cli/utils/keys.py:
--------------------------------------------------------------------------------
1 | from cryptography.hazmat.backends import default_backend
2 | from cryptography.hazmat.primitives import serialization
3 | from cryptography.hazmat.primitives.asymmetric import rsa
4 |
5 |
6 | def generate_keys():
7 | """
8 | Generates openssl public and private key pairs.
9 |
10 | Returns:
11 | key_pair_map (dict) = a dict with both the public and private keys.
12 | """
13 | key_pair_map = {}
14 | # generate private key & write to disk
15 | private_key = rsa.generate_private_key(
16 | public_exponent=65537,
17 | key_size=4096,
18 | backend=default_backend()
19 | )
20 | pem = private_key.private_bytes(
21 | encoding=serialization.Encoding.PEM,
22 | format=serialization.PrivateFormat.PKCS8,
23 | encryption_algorithm=serialization.NoEncryption()
24 | )
25 | key_pair_map['PRIVATE_KEY'] = pem.decode('utf-8')
26 |
27 | # generate public key
28 | public_key = private_key.public_key()
29 | pem = public_key.public_bytes(
30 | encoding=serialization.Encoding.PEM,
31 | format=serialization.PublicFormat.SubjectPublicKeyInfo
32 | )
33 | key_pair_map['PUBLIC_KEY'] = pem.decode('utf-8')
34 |
35 | return key_pair_map
36 |
--------------------------------------------------------------------------------
/cli/README.md:
--------------------------------------------------------------------------------
1 | # OIDC Configuration Generator CLI
2 |
3 | Ensure that you have installed `Python3` and `Pip3` as part of the Pre-requisites.
4 |
5 | ## Install Python Dependencies
6 |
7 | ```sh
8 | pip install -r requirements.txt
9 | ```
10 |
11 | ## Use the CLI
12 |
13 | ```sh
14 | python cli.py \
15 | --client_id client-id \
16 | --client_secret client-secret \
17 | --cloudfront_host cloudfront-host \
18 | --idp_domain_name idp-domain-name \
19 | --idp_name idp
20 | ```
21 |
22 | ### Arguments / Flags
23 |
24 | - `--client_id` **(required)** = the IdP Registered Application Client ID.
25 | - `--client_secret` **(required)** = the IdP Registered Application Client Secret.
26 | - `--cloudfront_host` **(required)** = the host name of the Amazon Cloudfront Distribution.
27 | - `--idp_domain_name` **(required)** = the domain name generated by your IdP for OIDC.
28 | - `--idp_name` **(required)** = the name of your IdP (e.g. Cognito).
29 |
30 | This will produce the following two files in the same directory:
31 | 1. `cloudfront_config_rendered.json` = this is the rendered configuration file with all of the supplied parameters from the CLI above.
32 | 2. `encoded_cloudfront_config_rendered.json` = this is the key-value pair JSON document with the Base64 encoded JSON document from the first file. It is a key-value pair in the format that this should be stored in AWS Secrets Manager.
33 |
34 |
--------------------------------------------------------------------------------
/cli/cli.py:
--------------------------------------------------------------------------------
1 | import json
2 | import click
3 | import base64
4 | from utils import keys
5 | from utils import generator
6 |
7 | """
8 | client_id: str,
9 | client_secret: str,
10 | cloudfront_host: str,
11 | idp_domain_name: str,
12 | openssl_private_key: str,
13 | openssl_public_key: str,
14 | idp_name="idp"
15 | """
16 |
17 | @click.command()
18 | @click.option('--client_id', help='The Registered Application Client ID')
19 | @click.option('--client_secret', help='The Registered Application Client Secret')
20 | @click.option('--cloudfront_host', help='The hostname of the Amazon CloudFront distribution')
21 | @click.option('--idp_domain_name', help='The hostname for the IdP')
22 | @click.option('--idp_name', default='idp', help='The type of the IdP - e.g. cognito')
23 | def generate_configuration(
24 | client_id: str,
25 | client_secret: str,
26 | cloudfront_host: str,
27 | idp_domain_name: str,
28 | idp_name="idp"
29 | ):
30 | # generate public/private key pair
31 | key_pair = keys.generate_keys()
32 |
33 | # extract public and private keys individually
34 | public_key = key_pair['PUBLIC_KEY']
35 | private_key = key_pair['PRIVATE_KEY']
36 |
37 | generator.generate_rendered_config_file(
38 | client_id=client_id,
39 | client_secret=client_secret,
40 | cloudfront_host=cloudfront_host,
41 | idp_domain_name=idp_domain_name,
42 | openssl_private_key=private_key,
43 | openssl_public_key=public_key,
44 | idp_name=idp_name
45 | )
46 |
47 | generator.base_64_encode_config(
48 | config_file='cloudfront_config_rendered.json'
49 | )
50 |
51 | if __name__ == '__main__':
52 | generate_configuration()
53 |
--------------------------------------------------------------------------------
/docs/keycloak.md:
--------------------------------------------------------------------------------
1 | # Keycloak IdP Setup
2 |
3 | [Keycloak](https://www.keycloak.org/) can be used as an IdP (Identity Provider) to secure the Amazon CloudFront Distribution created by this repository.
4 |
5 | ## Configure Keycloak
6 |
7 | In order to get started, login to Keycloak with an identity that has the ability to create a new Application.
8 |
9 | 1. Navigate to `Clients` on the left of the screen and fill-in specific details about the client you would like to create like below:
10 |
11 | 
12 |
13 | 2. Click on `Next`. On the next page choose the settings that work for you and your organization. At a minimum, ensure that under `Authentication flow` that `Standard flow` is checked and click `Save` like below:
14 |
15 | 
16 |
17 | 3. On the next page under `Client details` navigate to the `Access settings` and at a very minimum configure the `Valid redirect URIs` with your Amazon CloudFront Distribution URL with the `/_callback` value appended to it and click on `Save` at the bottom of the screen:
18 |
19 | 
20 |
21 | 4. Navigate back to the `Clients` section on the left of the screen and click on the Client you just registered. Scroll down to `Advanced Settings` and under the `Proof Key for Code Exchange Code Challenge Method` choose `S256` and click `Save`:
22 |
23 | 
24 |
25 | 5. Update the AWS Secrets Manager Configuration with the appropriate IDP URL and the Client ID. The Client ID will be the value that you gave to the application during the Client Creation process. In this cae it will be `my-cloudfront-distribution-application`. There is no Client Secret used so this value can be ignored since you will use [PKCE](https://oauth.net/2/pkce/) or Proof Key for Code Exchange to securely interact with the IDP and the Amazon CloudFront Distribution.
26 |
27 | 6. That is all!
--------------------------------------------------------------------------------
/docs/baseconfiguration.md:
--------------------------------------------------------------------------------
1 | ## Base Configuration
2 |
3 | The first step for deploying this solution is to create a dummy configuration placeholder and store it into AWS Secrets Manager. For the time-being, this is just a placeholder and we will come back and update this later.
4 |
5 | **NOTE (Very Important!):** In the [src/js](../src/js) directory of this project, there is a file called `sm-key.txt`. This file is used by the Lambda@Edge function to determine which AWS Secrets Manager secret to pull the configurations from. It is very important that this name matches the name you give the Secret in step 7 of these instructions. For example, if you name your placeholder secret `my-cloudfront-secret`, the `sm-key.txt` file must also contain a string called `my-cloudfront-secret`.
6 |
7 | 1. Navigate to the AWS Console
8 | 2. Search for `Secrets Manager` and click on this service
9 | 3. Click on `Store a new secret`
10 | 4. For the `Secret type` select `Other type of secret`
11 | 5. In the `Key/value pairs` section, provide the following details:
12 | - `Key` = config
13 | - `Value` = PLACEHOLDER
14 |
15 | 
16 | 6. Select the appropriate `Encryption key` settings for your organization's needs. The default is to use the `aws/secretsmanager` key.
17 | 7. Provide the `Secret name` - which is "cloudfront/DISTRIBUTION_ID", along with an appropriate `Description` and a set of `Tags` that make it easy to identify the Secret. For now, you can skip `Resource permissions` - you will come back to this later.
18 |
19 | 
20 |
21 | 8. Click on the `Next` button.
22 | 9. Provide the `Secret rotation` settings or leave it as the default.
23 | 10. Click on `Next`.
24 | 11. Click `Store`.
25 | 12. Click on the Secret that was just created.
26 | 13. Under the `Secret details` section, copy the `Secret ARN` and save this to a notepad for later use.
27 | 14. Move on to the next step!
28 |
29 | ### Next Step
30 |
31 | Navigate to [Deploy the AWS SAM Stack](deploy.md) for the next step.
32 |
--------------------------------------------------------------------------------
/docs/cognito.md:
--------------------------------------------------------------------------------
1 | # Amazon Cognito IdP Setup
2 |
3 | [Amazon Cognito](https://aws.amazon.com/cognito/) can be used as an IdP (Identity Provider) to secure the Amazon CloudFront Distribution created by this repository.
4 |
5 | ## Configure Amazon Cognito
6 |
7 | In order to get started, login to the [AWS Console](https://aws.amazon.com/console/) with an identity that has the ability to manage Amazon Cognito User Pools and App integrations.
8 |
9 | 1. Search for `Cognito` in the search bar and click on the `Cognito` service.
10 | 2. Click on `Manage User Pools` next:
11 | 
12 | 3. Select an existing User Pool or Create a user pool by clicking on the `Create a user pool` button in the top-left corner of the page.
13 | 4. After selecting an existing Cognito User Pool or creating a new User Pool, navigate to `App integration > App client settings` on the left of the page:
14 | 
15 | 5. On the `App client settings` page select the following:
16 | 5a. `Enabled Identity Providers` = check the `Cognito User Pool`
17 | 5b. `Sign in and sign out URLs` = for `Callback URL(s)` provide the Amazon CloudFront distribution HTTPS endpoint with `_callback` appended to the end. Provide the appropriate `Sign out URL(s)` value that is suitable.
18 | 5c. `OAuth 2.0` = At the minimum for `Allowed OAuth Flows` check `Authorization code grant`. For `Allowed OAuth Scopes` check `email` and `openid` at the minimum.
19 | 
20 | 6. After providing the necessary arguments click on `Save changes`.
21 | 7. On the next page, provide an appropriate `Amaon Cognito domain` endpoint:
22 | 
23 | 8. Navigate back to the `General settings` and click on `App Clients`.
24 | 9. Create a new App client and provide it a name that is suitable for your Amazon CloudFront use-case. Select the appropriate `Auth Flows Configuration` and then click save.
25 | 10. Expand the newly-create App Client and copy the `App client id` and the `App client secret` into a secure location that can be later referenced.
26 | 11. Update the AWS Secrets Manager JSON configuration with these values and Base64 Encode the document.
27 | 12. Congratulations! You are ready to go!
28 |
29 |
--------------------------------------------------------------------------------
/docs/okta.md:
--------------------------------------------------------------------------------
1 | # Okta IdP Setup
2 |
3 | [Okta](https://www.okta.com/) can be used as an IdP (Identity Provider) to secure the Amazon CloudFront Distribution created by this repository.
4 |
5 | ## Configure Okta
6 |
7 | In order to get started, login to Okta with an identity that has the ability to create a new Application.
8 |
9 | 1. Navigate to **Applications** > **Applications**
10 | 
11 |
12 | 2. Click on **Create App Integration** and select the following options:
13 | 
14 |
15 | The following options should be selected:
16 | - `Sign-in method:` **OIDC - OpenID Connect**
17 | - `Application type:` **Web Application**
18 |
19 | 3. On the next page under **General Settings** ensure the following are selected:
20 | 
21 |
22 | The following options should be selected:
23 | - `Client acting on behalf of a user:` **Authorization Code**
24 |
25 | Feel free to name the application anything that suits your use-case and is easy for you and your organization to understand.
26 |
27 | 4. Navigate to your AWS Account and obtain the generated HTTPS Amazon CloudFront endpoint generated. This will be in the form of **https://xyz.cloudfront.net**. Copy this full link and save it to in a text editor for the next step.
28 |
29 | 5. Navigate back to the Okta Application Registration page. Under the **Sign-in redirect URIs** section, paste in the Amazon CloudFront distribution link obtained from Step 4 and add it as a new Sign-In Redirect URI and appen `/_callback` to the end of the link. As an example, please see the following format: `https://xyz.cloudfront.net/_callback`.
30 |
31 | 
32 |
33 | 6. Under the **Assignments** section on the Okta web page, select the set of groups in your organization to scope this Application usage to. Or allow all users (depending on your use-case).
34 |
35 | 
36 |
37 | 7. Click on `Save` after you have selected all relevant options and configurations for your use-case.
38 |
39 | 8. Navigate back to the **Applications** section in Okta and click on the newly-created Application registered from above. Securely copy the **Client ID** and the **Client Secret** values
40 |
41 | 
42 |
43 | 9. Update the AWS Secrets Manager Secret with the Application Client ID and the Client Secret and Base64 encode the JSON document.
44 |
45 | 10. Congratulations! You have configured your Amazon CloudFront Distribution with Okta!
46 |
--------------------------------------------------------------------------------
/docs/deploy.md:
--------------------------------------------------------------------------------
1 | # Deploy this Solution
2 |
3 | **Please note the Pre-requisites on the landing page before continuing forward!**
4 |
5 | ## 1. Set up the following environment variables in your environment:
6 |
7 | Please export the following variables before running the steps below:
8 | - `SAM_DEPLOYMENT_BUCKET` = this is an **existing** AWS S3 bucket in the same region for SAM artifacts to be staged in
9 | - `NEW_LOG_BUCKET_NAME` = the name of the **new** AWS S3 Bucket to create for logging and auditing
10 | - `NEW_STATIC_SITE_BUCKET_NAME` = the name of the **new** AWS S3 Bucket to store all static content to be served up by the Amazon CloudFront Distribution
11 | - `SECRETS_MANAGER_KEY_ARN` = the ARN of the AWS Secrets Manager Key created for storing relevant OIDC Application Information. This is the Secrets Manager Secret ARN copied from the prior step.
12 |
13 | ### Example Export of Environment Variables
14 |
15 | **NOTE: Replace the corresponding
16 |
17 | **Mac/Linux/Unix:**
18 |
19 | ```sh
20 | export SAM_DEPLOYMENT_BUCKET=my-bucket-name
21 | export NEW_LOG_BUCKET_NAME=my-new-logging-bucket
22 | export NEW_STATIC_SITE_BUCKET_NAME=my-new-static-content-bucket
23 | export SECRETS_MANAGER_KEY_ARN=arn:aws:secretsmanager:us-east-1:012345678910:secret:secretName
24 | ```
25 |
26 | **Windows:**
27 |
28 | ```cmd
29 | set SAM_DEPLOYMENT_BUCKET=my-bucket-name
30 | set NEW_LOG_BUCKET_NAME=my-new-logging-bucket
31 | set NEW_STATIC_SITE_BUCKET_NAME=my-new-static-content-bucket
32 | set SECRETS_MANAGER_KEY_ARN=arn:aws:secretsmanager:us-east-1:012345678910:secret:secretName
33 | ```
34 |
35 | ## 2. AWS SAM Deployment Commands
36 | a. Build lambda function, and prepare them for subsequent steps in the workflow
37 |
38 | ```sh
39 | sam build -b ./build -s . -t template.yaml -u
40 | ```
41 |
42 | b. Packages the above LambdaFunction. It creates a ZIP file of the code and dependencies, and uploads it to Amazon S3 (please create the S3 bucket and mention the bucket name in the command below). It then returns a copy of AWS SAM template, replacing references to local artifacts with the Amazon S3 location where the command uploaded the artifacts
43 |
44 | ```sh
45 | sam package \
46 | --template-file build/template.yaml \
47 | --s3-bucket ${SAM_DEPLOYMENT_BUCKET} \
48 | --output-template-file build/packaged.yaml
49 | ```
50 |
51 | c. Deploy Lambda functions through AWS CloudFormation from the S3 bucket created above. AWS SAM CLI now creates and manages this Amazon S3 bucket for you.
52 |
53 | ```sh
54 | sam deploy \
55 | --template-file build/packaged.yaml \
56 | --stack-name oidc-auth \
57 | --capabilities CAPABILITY_NAMED_IAM \
58 | --parameter-overrides BucketName=${NEW_STATIC_SITE_BUCKET_NAME} LogBucketName=${NEW_LOG_BUCKET_NAME} SecretKeyArn=${SECRETS_MANAGER_KEY_ARN}
59 | ```
60 |
61 | ### Next Step
62 |
63 | Navigate to [Set up Registered OIDC Application](registerapplication.md) for the next step.
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Amazon CloudFront and Lambda@Edge OIDC Function
2 |
3 | ## Purpose
4 |
5 | Create a globally-distributed Amazon CloudFront Distribution (CDN) that will securely serve-up static files from an Amazon S3 Bucket using OpenID Connect. The purpose of this repository is to allow organizations or users to integrate with their preferred OpenID Connect compliant Identity Provider (IdP).
6 |
7 | ## Pre-requisites
8 |
9 | - [AWS SAM CLI is Installed](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
10 | - [AWS Credentials are setup in your Environment](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html)
11 | - [An S3 Bucket is created in your AWS account in the Same Region you are deploying to](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)
12 | - [Python3 is Installed in your Environment](https://www.python.org/downloads/)
13 | - [Pip3 is Installed in your Environment](https://pip.pypa.io/en/stable/installation/)
14 |
15 | ## Steps For Setup
16 |
17 | The following set of steps should be followed to deploy this solution:
18 |
19 | 1. [Create a base AWS Secrets Manager Secret Configuration](docs/baseconfiguration.md)
20 | 2. [Deploy the AWS SAM Stack](docs/deploy.md)
21 | 3. [Set up Registered OIDC Application](docs/registerapplication.md)
22 | 4. [Generate OIDC Configuration](docs/configuration.md)
23 | 5. [Update AWS Secrets Manager](docs/secretsmanager.md)
24 | 6. [Navigate to Amazon CloudFront URL / Troubleshoot](docs/cloudfront.md)
25 |
26 | ## Configuration CLI
27 |
28 | For more details about generating the configuration file for AWS Secrets Manager please refer to [CLI Documentation](cli/README.md)
29 |
30 | ## Request Flow
31 |
32 | 
33 |
34 | 1. User requests content from Amazon CloudFront Distribution
35 | 2. AWS Lambda@Edge Viewer Request invoked
36 | 1. If valid authentication cookie present in header, redirect to Amazon S3 Bucket.
37 | 2. If no authentication cookie is present or expired/invalid cookie header is present, continue to step 3.
38 | 3. AWS Lambda@Edge Function redirects request to IdP for Authentication request.
39 | 1. If Authentication challenge fails - deny access and exit.
40 | 2. If Authentication challenge succeeds - continue on.
41 | 4. Retrieve object from Amazon S3 bucket and return content to requestor via Amazon CloudFront Distribution. User is happy :)
42 |
43 | ### TL;DR
44 |
45 | #### This will create the following AWS infrastructure
46 |
47 | - S3 Data Bucket
48 | - S3 Logging Bucket
49 | - CloudFront Distribution
50 | - Lambda@Edge Function for OIDC Auth
51 |
52 | ## Troubleshooting
53 |
54 | Please refer to this [document](docs/cloudfront.md) for Troubleshooting common scenarios. Open a GitHub issue if this does not help!
55 |
56 | ## Identity Provider (IdP) Setup Instructions
57 | - [Amazon Cognito Application Registration](docs/cognito.md)
58 | - [Okta Application Registration](docs/okta.md)
59 | - [Keycloak Client Creation and Registration](docs/keycloak.md)
60 |
61 |
62 | ## Security
63 |
64 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
65 |
66 | ## License
67 |
68 | This library is licensed under the MIT-0 License. See the LICENSE file.
69 |
70 | ## Contributors
71 |
72 | - Viyoma Sachdeva
73 | - Matt Noyce
74 |
--------------------------------------------------------------------------------
/cli/utils/generator.py:
--------------------------------------------------------------------------------
1 | import json
2 | import base64
3 |
4 | configuration = {
5 | "AUTH_REQUEST": {
6 | "client_id": "$CLIENT_ID_FROM_IDP",
7 | "response_type": "code",
8 | "scope": "openid email profile",
9 | "redirect_uri": "https://$CLOUDFRONT_DIST_URL/_callback"
10 | },
11 | "TOKEN_REQUEST": {
12 | "client_id": "$CLIENT_ID_FROM_IDP",
13 | "redirect_uri": "https://$CLOUDFRONT_DIST_URL/_callback",
14 | "grant_type": "authorization_code",
15 | "client_secret": "$CLIENT_SECRET_FROM_IDP"
16 | },
17 | "DISTRIBUTION": "amazon-oai",
18 | "AUTHN": "$IDP_NAME",
19 | "PRIVATE_KEY": "$PRIVATE_KEY_GOES_HERE",
20 | "PUBLIC_KEY": "$PUBLIC_KEY_GOES_HERE",
21 | "DISCOVERY_DOCUMENT": "https://$IDP_DOMAIN_NAME/.well-known/openid-configuration",
22 | "SESSION_DURATION": 300,
23 | "BASE_URL": "https://$IDP_DOMAIN_NAME/",
24 | "CALLBACK_PATH": "/_callback",
25 | "AUTHZ": "$IDP_NAME"
26 | }
27 |
28 | def scaffold_base_config_file():
29 | """
30 | Scaffolds out config file.
31 |
32 | Returns:
33 | config (file) = a base config file written to disk.
34 | """
35 |
36 | with open('cloudfront_config.json', 'w') as file:
37 | file.write(
38 | json.dumps(
39 | configuration,
40 | indent = 4
41 | )
42 | )
43 |
44 | def generate_rendered_config_file(
45 | client_id: str,
46 | client_secret: str,
47 | cloudfront_host: str,
48 | idp_domain_name: str,
49 | openssl_private_key: str,
50 | openssl_public_key: str,
51 | idp_name="idp"
52 | ):
53 | """
54 | Generates full configuration file with real values.
55 |
56 | Returns:
57 | config (file) = rendered configuration file.
58 | """
59 |
60 | base_config = {
61 | "AUTH_REQUEST": {
62 | "client_id": f"{client_id}",
63 | "response_type": "code",
64 | "scope": "openid email profile",
65 | "redirect_uri": f"https://{cloudfront_host}/_callback"
66 | },
67 | "TOKEN_REQUEST": {
68 | "client_id": f"{client_id}",
69 | "redirect_uri": f"https://{cloudfront_host}/_callback",
70 | "grant_type": "authorization_code",
71 | "client_secret": f"{client_secret}"
72 | },
73 | "DISTRIBUTION": "amazon-oai",
74 | "AUTHN": f"{idp_name}",
75 | "PRIVATE_KEY": f"{openssl_private_key}",
76 | "PUBLIC_KEY": f"{openssl_public_key}",
77 | "DISCOVERY_DOCUMENT": f"https://{idp_domain_name}/.well-known/openid-configuration",
78 | "SESSION_DURATION": 300,
79 | "BASE_URL": f"https://{idp_domain_name}/",
80 | "CALLBACK_PATH": "/_callback",
81 | "AUTHZ": f"{idp_name}"
82 | }
83 |
84 | with open('cloudfront_config_rendered.json', 'w') as file:
85 | file.write(
86 | json.dumps(
87 | base_config,
88 | indent = 4
89 | )
90 | )
91 |
92 | def base_64_encode_config(
93 | config_file
94 | ):
95 | with open(config_file, 'r') as file:
96 | config_contents = file.read()
97 | config_bytes = config_contents.encode()
98 | file.close()
99 |
100 | with open(f"encoded_{config_file}", 'w') as file:
101 | encoded_config = base64.b64encode(config_bytes).decode('ASCII')
102 | file.write(
103 | json.dumps({
104 | "config": encoded_config
105 | }, indent = 4)
106 | )
107 |
108 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *master* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 |
43 | ## Finding contributions to work on
44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
45 |
46 |
47 | ## Code of Conduct
48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50 | opensource-codeofconduct@amazon.com with any additional questions or comments.
51 |
52 |
53 | ## Security issue notifications
54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55 |
56 |
57 | ## Licensing
58 |
59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
60 |
61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
62 |
--------------------------------------------------------------------------------
/src/js/lib/log/index.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for Log
2 | // Project: Log
3 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 | // SPDX-License-Identifier: MIT-0
5 | export = Log;
6 |
7 | /**
8 | * Log is a JSON logger for facilitating structured logging that can be correlated
9 | * between multiple lambda functions via CloudWatch logs.
10 | *
11 | * To use:
12 | * 1. Import `const Log = require('./lib/log)`
13 | * 2. Create an instance id
14 | * a. Create instance with custom instanceId: `const log = new Log('instanceId');`
15 | * b. Create instance with random uuid instanceId: `const log = new Log();`
16 | * c. Create instance with id from lambda event/context: `const log = new Log(event, context);`
17 | * 3. Add some properties to every log message: `log.addProp('myKey', 'some js value');`
18 | * 3. Log some info: `log.info('Hi', {'someAttribute': 'Here is some data to pass'});`
19 | * 4. Log an error: `log.error('Something failed', undefined, {'message': 'Something bad'});`
20 | *
21 | * Notes:
22 | * You can specify the log level to log with the LOG_LEVEL environment variable. Valid levels are
23 | * off, fatal, error, warn, info, debug, all. Default is info.
24 | * You can have the logs print human readable by setting the PRETTY_PRINT environment variable to
25 | * true. Default is false.
26 | *
27 | * @param event is an event containing values which could be used as a string id, or a string id.
28 | * if it is undefined or null, or can't be parsed, an id will be generated.
29 | * @param context is a lambda context, from which a request id could be harvested. If it
30 | * is undefined it is skipped.
31 | */
32 | export function log(event?: any, context?: any): Log;
33 |
34 | export interface Log {
35 | /** instanceId returns the instance id of the logger. */
36 | instanceId(): string;
37 |
38 | /**
39 | * addProp adds a property to all of the log messages
40 | *
41 | * @param key is the key of the property to add
42 | * @param property is the value to add
43 | */
44 | addProp(key: string, property: any): undefined;
45 |
46 | /**
47 | * rmProp removes a property from all of the log messages
48 | *
49 | * @param key is the key of the property to remove
50 | */
51 | rmProp(key: string): undefined;
52 |
53 | /**
54 | * info logs an info message
55 | *
56 | * @param message message to log
57 | * @param attributes additional attributes to log
58 | * @param error error to log
59 | */
60 | info(message: string, attributes?: any, error?: Error): undefined;
61 |
62 | /**
63 | * warn logs a warn message
64 | *
65 | * @param message message to log
66 | * @param attributes additional attributes to log
67 | * @param error error to log
68 | */
69 | warn(message: string, attributes?: any, error?: Error): undefined;
70 |
71 | /**
72 | * debug logs a debug message
73 | *
74 | * @param message message to log
75 | * @param attributes additional attributes to log
76 | * @param error error to log
77 | */
78 | debug(message: string, attributes?: any, error?: Error): undefined;
79 |
80 | /**
81 | * error logs an error messages
82 | *
83 | * @param message message to log
84 | * @param attributes additional attributes to log
85 | * @param error error to log
86 | */
87 | error(message: string, attributes?: any, error?: Error): undefined;
88 |
89 | /**
90 | * fatal logs a fatal message
91 | *
92 | * @param message message to log
93 | * @param attributes additional attributes to log
94 | * @param error error to log
95 | */
96 | fatal(message: string, attributes?: any, error?: Error): undefined;
97 | }
98 |
--------------------------------------------------------------------------------
/docs/configuration.md:
--------------------------------------------------------------------------------
1 | # Create OIDC Configuration
2 |
3 | In order to use this solution a configuration document must be generated. Here are two ways that this configuration can be generated:
4 |
5 | ## 1. Use the Configuration CLI
6 |
7 | The configuration CLI is a Python3 script that will automate the generation of the Amazon CloudFront Distribution configuration.
8 |
9 | In the [CLI Directory](../cli) there is a CLI utility that will help generate the JSON configuration and then Base64 encode it. This utility will also generated OpenSSL private and public key pairs that are required.
10 |
11 | ### Example CLI Execution
12 |
13 | ```sh
14 | python cli.py \
15 | --client_id client-id \
16 | --client_secret client-secret \
17 | --cloudfront_host cloudfront-host \
18 | --idp_domain_name idp-domain-name \
19 | --idp_name idp
20 | ```
21 |
22 | This will produce the following two files in the same directory:
23 | 1. `cloudfront_config_rendered.json` = this is the rendered configuration file with all of the supplied parameters from the CLI above.
24 | 2. `encoded_cloudfront_config_rendered.json` = this is the key-value pair JSON document with the Base64 encoded JSON document from the first file. It is a key-value pair in the format that this should be stored in AWS Secrets Manager.
25 |
26 | Copy the encoded value from `encoded_cloudfront_config_rendered.json` and move on to the next step.
27 |
28 | ## 2. ALTERNATE: Manually Create the Configuration
29 |
30 | The decoded JSON configuration document looks like the following:
31 |
32 | ```json
33 | {
34 | "AUTH_REQUEST": {
35 | "client_id": "${CLIENT_ID_FROM_IDP}",
36 | "response_type": "code",
37 | "scope": "openid email",
38 | "redirect_uri": "https://${CLOUDFRONT_DIST_URL}/_callback"
39 | },
40 | "TOKEN_REQUEST": {
41 | "client_id": "${CLIENT_ID_FROM_IDP}",
42 | "redirect_uri": "https://${CLOUDFRONT_DIST_URL}/_callback",
43 | "grant_type": "authorization_code",
44 | "client_secret": "${CLIENT_SECRET_FROM_OKTA}"
45 | },
46 | "DISTRIBUTION": "amazon-oai",
47 | "AUTHN": "OKTA",
48 | "PRIVATE_KEY": "${PRIVATE_KEY_GOES_HERE}",
49 | "PUBLIC_KEY": "${PUBLIC_KEY_GOES_HERE}",
50 | "DISCOVERY_DOCUMENT": "https://${IDP_DOMAIN_NAME}/.well-known/openid-configuration",
51 | "SESSION_DURATION": 30,
52 | "BASE_URL": "https://${IDP_DOMAIN_NAME}/",
53 | "CALLBACK_PATH": "/_callback",
54 | "AUTHZ": "OKTA"
55 | }
56 | ```
57 |
58 | In each of the sections above, notice there are key-value pairs. The values that contain `${}` must be filled-in and replaced accordingly.
59 |
60 | ### Document Arguments
61 |
62 | - `CLIENT_ID_FROM_IDP` = This is the Client ID generated from the registered application from the IdP.
63 | - `CLOUDFRONT_DIST_URL` = This is the Amazon CloudFront Distribution hostname for the distribution created. This will be in the form of `xyz.cloudfront.net`.
64 | - `PRIVATE_KEY_GOES_HERE` = This is a private key that is generated using a tool such as `openssl`. See the example below for the formatting.
65 | - `PUBLIC_KEY_GOES_HERE` = This is a public key that is generated using a tool such as `openssl`. See the example below for the formatting.
66 | - `IDP_DOMAIN_NAME` = This is the generated host name from the IdP you have selected. An example would be `dev-xyz-okta.com`.
67 |
68 | ### Generate
69 |
70 | ### Example Document Manually Created
71 |
72 | For an example, the manually-created example document would look like the following:
73 |
74 |
75 | ```json
76 | {
77 | "AUTH_REQUEST": {
78 | "client_id": "abcdefghijklmnop",
79 | "response_type": "code",
80 | "scope": "openid email",
81 | "redirect_uri": "https://xyz.cloudfront.net/_callback"
82 | },
83 | "TOKEN_REQUEST": {
84 | "client_id": "abcdefghijklmnop",
85 | "redirect_uri": "https://xyz.cloudfront.net/_callback",
86 | "grant_type": "authorization_code",
87 | "client_secret": "secretvalue"
88 | },
89 | "DISTRIBUTION": "amazon-oai",
90 | "AUTHN": "IDP",
91 | "PRIVATE_KEY": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKQIBAAKCAgEAn9XzZ+C...xzU\n-----END RSA PRIVATE KEY-----\n",
92 | "PUBLIC_KEY": "----BEGIN PUBLIC KEY-----\nMIICIjANBg...AAQ==\n-----END PUBLIC KEY-----\n",
93 | "DISCOVERY_DOCUMENT": "https://idp-generated-hostname/.well-known/openid-configuration",
94 | "SESSION_DURATION": 30,
95 | "BASE_URL": "https://idp-generated-hostname/",
96 | "CALLBACK_PATH": "/_callback",
97 | "AUTHZ": "IDP"
98 | }
99 | ```
100 | ### Base64 Encode the Configuration
101 |
102 | 1. Store this JSON document to a file called `configuration.json`.
103 | 2. Run the following command:
104 | ```sh
105 | openssl base64 -in configuration.json -out configuration-encoded.json
106 | ```
107 | 3. Copy the contents of `configuration-encoded.json` and move on to the next step of updating the AWS Secrets Manager OIDC Secret.
108 |
109 |
110 | ### Next Step
111 |
112 | Navigate to [Update AWS Secrets Manager](secretsmanager.md) for the next step.
113 |
--------------------------------------------------------------------------------
/template.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | # SPDX-License-Identifier: MIT-0
3 | AWSTemplateFormatVersion: '2010-09-09'
4 | Transform: AWS::Serverless-2016-10-31
5 | Description: SAM configuration for cloudfront-auth function
6 | Parameters:
7 | BucketName:
8 | Type: String
9 | Description: The name of the Static Content S3 Bucket to Create
10 | LogBucketName:
11 | Type: String
12 | Description: The name of the Log Content S3 Bucket already existing
13 | SecretKeyArn:
14 | Type: String
15 | Description: The ARN of the Secret in Secrets manager for the OIDC configuaration (e.g. okta-configuration-v4cw9Z)
16 | MinimumTLSVersion:
17 | Type: String
18 | Description: The minimum version to use for CloudFront TLS
19 | Default: TLSv1.2_2018
20 | Resources:
21 | LoggingBucket:
22 | Type: AWS::S3::Bucket
23 | Properties:
24 | AccessControl: LogDeliveryWrite
25 | BucketName: !Ref LogBucketName
26 | BucketEncryption:
27 | ServerSideEncryptionConfiguration:
28 | -
29 | ServerSideEncryptionByDefault:
30 | SSEAlgorithm: AES256
31 | S3Bucket:
32 | Type: AWS::S3::Bucket
33 | Properties:
34 | BucketName: !Ref BucketName
35 | BucketEncryption:
36 | ServerSideEncryptionConfiguration:
37 | -
38 | ServerSideEncryptionByDefault:
39 | SSEAlgorithm: AES256
40 | LoggingConfiguration:
41 | DestinationBucketName: !Ref LoggingBucket
42 | LogFilePrefix: "accessLogs/"
43 | ReadPolicy:
44 | Type: AWS::S3::BucketPolicy
45 | Properties:
46 | Bucket: !Ref S3Bucket
47 | PolicyDocument:
48 | Statement:
49 | - Action: 's3:GetObject'
50 | Effect: Allow
51 | Resource: !Sub 'arn:aws:s3:::${S3Bucket}/*'
52 | Principal:
53 | CanonicalUser: !GetAtt CloudFrontOriginAccessIdentity.S3CanonicalUserId
54 | CloudFrontOriginAccessIdentity:
55 | Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
56 | Properties:
57 | CloudFrontOriginAccessIdentityConfig:
58 | Comment: !Ref S3Bucket
59 | CFDistribution:
60 | Type: AWS::CloudFront::Distribution
61 | Properties:
62 | DistributionConfig:
63 | ViewerCertificate:
64 | CloudFrontDefaultCertificate: 'true'
65 | MinimumProtocolVersion: !Ref MinimumTLSVersion
66 | Logging:
67 | Bucket: !GetAtt LoggingBucket.DomainName
68 | IncludeCookies : "true"
69 | Prefix: "cloudfront/"
70 | Enabled: 'true'
71 | Origins:
72 | - DomainName: !GetAtt S3Bucket.DomainName
73 | Id: myS3Origin
74 | S3OriginConfig:
75 | OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}'
76 | Enabled: 'true'
77 | Comment: Amazon CloudFront Distribution Secured by OIDC
78 | DefaultRootObject: index.html
79 | DefaultCacheBehavior:
80 | TargetOriginId: myS3Origin
81 | LambdaFunctionAssociations:
82 | -
83 | EventType: viewer-request
84 | LambdaFunctionARN: !Ref CloudFrontAuthFunction.Version
85 | ForwardedValues:
86 | QueryString: 'false'
87 | Headers:
88 | - Origin
89 | Cookies:
90 | Forward: none
91 | ViewerProtocolPolicy:
92 | "allow-all"
93 | CloudFrontAuthFunction:
94 | Type: AWS::Serverless::Function
95 | Properties:
96 | CodeUri: src/js/
97 | Role: !GetAtt LambdaEdgeFunctionRole.Arn
98 | Runtime: nodejs20.x
99 | Handler: auth.handler
100 | Timeout: 5
101 | AutoPublishAlias: LIVE
102 | LambdaEdgeFunctionRole:
103 | Type: AWS::IAM::Role
104 | Properties:
105 | Path: "/"
106 | ManagedPolicyArns:
107 | - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
108 | Policies:
109 | - PolicyName: !Sub "Lambda-${AWS::StackName}"
110 | PolicyDocument:
111 | Version: "2012-10-17"
112 | Statement:
113 | - Effect: Allow
114 | Action:
115 | - "secretsmanager:GetResourcePolicy"
116 | - "secretsmanager:GetSecretValue"
117 | - "secretsmanager:DescribeSecret"
118 | - "secretsmanager:ListSecretVersionIds"
119 | Resource: !Ref SecretKeyArn
120 | AssumeRolePolicyDocument:
121 | Version: "2012-10-17"
122 | Statement:
123 | -
124 | Sid: "AllowLambdaServiceToAssumeRole"
125 | Effect: "Allow"
126 | Action:
127 | - "sts:AssumeRole"
128 | Principal:
129 | Service:
130 | - "lambda.amazonaws.com"
131 | - "edgelambda.amazonaws.com"
132 | Outputs:
133 | CloudFrontDomainName:
134 | Description: The Domain name of the Amazon CloudFront Distribution
135 | Value: !GetAtt CFDistribution.DomainName
136 | CloudFrontAuthFunction:
137 | Description: Lambda@Edge CloudFront Auth Function ARN
138 | Value: !GetAtt CloudFrontAuthFunction.Arn
139 | CloudFrontAuthFunctionVersion:
140 | Description: Lambda@Edge CloudFront Auth Function ARN with Version
141 | Value: !Ref CloudFrontAuthFunction.Version
142 |
--------------------------------------------------------------------------------
/src/js/lib/log/index.js:
--------------------------------------------------------------------------------
1 | // LogLevel defines the log level and hierarchy of log levels
2 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | // SPDX-License-Identifier: MIT-0
4 | let LogLevel;
5 | // eslint-disable-next-line func-names
6 | (function(logLevel) {
7 | const level = logLevel;
8 | level[(level.OFF = 0)] = 'OFF';
9 | level[(level.FATAL = 1)] = 'FATAL';
10 | level[(level.ERROR = 2)] = 'ERROR';
11 | level[(level.WARN = 3)] = 'WARN';
12 | level[(level.INFO = 4)] = 'INFO';
13 | level[(level.DEBUG = 5)] = 'DEBUG';
14 | level[(level.ALL = 6)] = 'ALL';
15 | })(LogLevel || (LogLevel = {}));
16 |
17 | /**
18 | * Log is a JSON logger for facilitating structured logging that can be correlated
19 | * between multiple lambda functions via CloudWatch logs.
20 | *
21 | * To use:
22 | * 1. Import `const Log = require('./lib/log)`
23 | * 2. Create an instance id
24 | * a. Create instance with custom instanceId: `const log = new Log('instanceId');`
25 | * b. Create instance with random uuid instanceId: `const log = new Log();`
26 | * c. Create instance with id from lambda event/context: `const log = new Log(event, context);`
27 | * 3. Add some properties to every log message: `log.addProp('myKey', 'some js value');`
28 | * 3. Log some info: `log.info('Hi', {'someAttribute': 'Here is some data to pass'});`
29 | * 4. Log an error: `log.error('Something failed', undefined, {'message': 'Something bad'});`
30 | *
31 | * Notes:
32 | * You can specify the log level to log with the LOG_LEVEL environment variable. Valid levels are
33 | * off, fatal, error, warn, info, debug, all. Default is info.
34 | * You can have the logs print human readable by setting the PRETTY_PRINT environment variable to
35 | * true. Default is false.
36 | *
37 | * @param {any?} event is an event containing values which could be used as a string id, or a
38 | * string id.
39 | * if it is undefined or null, or can't be parsed, an id will be generated.
40 | * @param {any?} context is a lambda context, from which a request id could be harvested. If it
41 | * is undefined
42 | * it is skipped.
43 | */
44 | function log(event, context) {
45 | const isPrettyPrint = (process.env.PRETTY_PRINT || 'false').toLowerCase() === 'true';
46 | const logLevel = getLogLevel(process.env.LOG_LEVEL || 'INFO');
47 | const lambdaName = getLambdaName();
48 | const properties = {};
49 | const id = getId(event, context);
50 |
51 | // log writes the logging payload to the stdout.
52 | const logMessage = (possibleLevel, message, attributes, error) => {
53 | // using stdout so I write pure json to the cloudwatch logs.
54 | const write = (value) => {
55 | if (isPrettyPrint) {
56 | process.stdout.write(`${customStringify(value, undefined, 2)}\n`);
57 | } else {
58 | process.stdout.write(`${customStringify(value)}\n`);
59 | }
60 | };
61 | const finalLevel = getLogLevel(possibleLevel || 'INFO');
62 | const valueToWrite = {
63 | instanceId: id,
64 | level: LogLevel[finalLevel],
65 | message: isNil(message) ? undefined : message,
66 | attributes: isNil(attributes) ? {} : attributes,
67 | properties: isNil(properties) ? {} : properties,
68 | error: isNil(error) ? undefined : { message: error.message, stack: error.stack },
69 | logName: lambdaName,
70 | date: new Date().toISOString()
71 | };
72 | if (logLevel === LogLevel.FATAL && finalLevel <= LogLevel.FATAL) {
73 | write(valueToWrite);
74 | } else if (logLevel === LogLevel.ERROR && finalLevel <= LogLevel.ERROR) {
75 | write(valueToWrite);
76 | } else if (logLevel === LogLevel.WARN && finalLevel <= LogLevel.WARN) {
77 | write(valueToWrite);
78 | } else if (logLevel === LogLevel.INFO && finalLevel <= LogLevel.INFO) {
79 | write(valueToWrite);
80 | } else if (logLevel === LogLevel.DEBUG && finalLevel <= LogLevel.DEBUG) {
81 | write(valueToWrite);
82 | } else if (logLevel === LogLevel.ALL && finalLevel <= LogLevel.ALL) {
83 | write(valueToWrite);
84 | } else {
85 | // write nothing
86 | }
87 | };
88 |
89 | return {
90 | instanceId: () => id,
91 | // eslint-disable-next-line no-return-assign
92 | addProp: (key, property) => (properties[key] = property),
93 | rmProp: (key) => delete properties[key],
94 | info: (message, attributes) => logMessage('INFO', message, attributes),
95 | warn: (message, attributes, error) => logMessage('WARN', message, attributes, error),
96 | debug: (message, attributes, error) => logMessage('DEBUG', message, attributes, error),
97 | error: (message, attributes, error) => logMessage('ERROR', message, attributes, error)
98 | };
99 | }
100 |
101 | // getId returns the event if it is a string. If the event is an event, it looks
102 | // for an instanceId in it. If the instanceId is not there, it checks the context for a
103 | // requestId and returns that. If none of those are available, it generates a uuid (which is
104 | // not a time based uuid)
105 | function getId(event, context) {
106 | if (typeof event === 'string') {
107 | return event;
108 | }
109 | if (event !== undefined && event.instanceId !== undefined) {
110 | return event.instanceId;
111 | }
112 | if (context !== undefined && context.awsRequestId !== undefined) {
113 | return context.awsRequestId;
114 | }
115 | const placeholder = '10000000-1000-4000-8000-100000000000';
116 | // eslint-disable-next-line no-bitwise
117 | return placeholder.replace(/[018]/g, () => (0 | (Math.random() * 16)).toString(16));
118 | }
119 |
120 | // getLogLevel sets the log level based on the environment variable that is set.
121 | function getLogLevel(potentialLogLevel) {
122 | let logLevel;
123 | switch (potentialLogLevel.toUpperCase()) {
124 | case 'OFF': {
125 | logLevel = LogLevel.OFF;
126 | break;
127 | }
128 | case 'FATAL': {
129 | logLevel = LogLevel.FATAL;
130 | break;
131 | }
132 | case 'ERROR': {
133 | logLevel = LogLevel.ERROR;
134 | break;
135 | }
136 | case 'WARN': {
137 | logLevel = LogLevel.WARN;
138 | break;
139 | }
140 | case 'INFO': {
141 | logLevel = LogLevel.INFO;
142 | break;
143 | }
144 | case 'DEBUG': {
145 | logLevel = LogLevel.DEBUG;
146 | break;
147 | }
148 | default: {
149 | logLevel = LogLevel.INFO;
150 | break;
151 | }
152 | }
153 | return logLevel;
154 | }
155 |
156 | // isNil checks if a value is undefined or null.
157 | function isNil(value) {
158 | return value === undefined || value === null;
159 | }
160 |
161 | // removeExtension removed the file extension.
162 | function removeExtension(value) {
163 | const index = value.lastIndexOf('.');
164 | if (index === -1) return value;
165 | return value.substr(0, index);
166 | }
167 |
168 | // getFileNameSansPathAndExtension removes the path and extension from the file name.
169 | function getFileNameSansPathAndExtension(value) {
170 | return removeExtension(value.split('/').slice(-1)[0]);
171 | }
172 |
173 | // Gets the filename of the lambda using this library. This is overly simple and will fail... but
174 | // until I have an example of it returning the wrong name, I am leaving it.
175 | function getLambdaName() {
176 | const details = new Error().stack.split('at ')[3].trim();
177 | const fileName = getFileNameSansPathAndExtension(details.split(':')[0]);
178 | return fileName;
179 | }
180 |
181 | function customStringify(value, replacer, space) {
182 | const cache = new Set();
183 | return JSON.stringify(
184 | value,
185 | (_, val) => {
186 | if (typeof val === 'object' && val !== null) {
187 | if (cache.has(val)) {
188 | try {
189 | return JSON.parse(JSON.stringify(val, replacer, space));
190 | } catch (err) {
191 | // eslint-disable-next-line consistent-return
192 | return;
193 | }
194 | }
195 | cache.add(val);
196 | }
197 | return val;
198 | },
199 | space
200 | );
201 | }
202 |
203 | module.exports = log;
204 |
--------------------------------------------------------------------------------
/src/js/auth.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-extraneous-dependencies
2 | // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | // SPDX-License-Identifier: MIT-0
4 |
5 | const { SecretsManager } = require('@aws-sdk/client-secrets-manager');
6 |
7 | const Axios = require('axios');
8 | const Cookie = require('cookie');
9 | const Crypto = require('crypto');
10 | const JsonWebToken = require('jsonwebtoken');
11 | const JwkToPem = require('jwk-to-pem');
12 | const QueryString = require('querystring');
13 | const Log = require('./lib/log');
14 | const Base64Url = require('base64url');
15 |
16 | let discoveryDocument;
17 | let secretId;
18 | let jwks;
19 | let config;
20 | let deps;
21 | let log;
22 | let pkceCodeVerifier;
23 | let pkceCodeChallenge;
24 |
25 | /**
26 | * handle is the starting point for the lambda.
27 | *
28 | * @param {Object} event is the event that initiates the handler
29 | * @param {AWS.Context} ctx is the aws lambda context
30 | * @param {(Error, any) => undefined} cb is the aws callback to signal completion. This is used
31 | * instead of the async method because it has more predictable behavior.
32 | * @param {object} setDependencies is a function that sets the dependencies If this is undefined
33 | * (as it will be in production) the setDependencies function in the module will set the
34 | * dependencies. If this value is specified (as it will be in tests) then deps will be
35 | * overwritten with the specified dependencies.
36 | */
37 | exports.handler = async (event, ctx, cb, setDeps = setDependencies) => {
38 | log = new Log(event, ctx);
39 | // log.info('init lambda', { event: event });
40 | deps = setDeps(deps);
41 | try {
42 | await prepareConfigGlobals(event);
43 | return await authenticate(event);
44 | } catch (err) {
45 | log.error(err.message, { event: event }, err);
46 | return getInternalServerErrorPayload(cb);
47 | }
48 | };
49 |
50 | // setDepedencies is used to allow the overwriting of module-level dependencies for the purpose of
51 | // testing. It's basically dependency injection.
52 | function setDependencies(dependencies) {
53 | if (dependencies === undefined || dependencies === null) {
54 | // log.info('setting up dependencies');
55 | return {
56 | axios: Axios,
57 | sm: new SecretsManager({ region: 'us-east-1' })
58 | };
59 | }
60 | return dependencies;
61 | }
62 |
63 | // authenticate authenticates the user if they are a valid user, otherwise redirects accordingly.
64 | async function authenticate(evt) {
65 | const { request } = evt.Records[0].cf;
66 | const { headers, querystring } = request;
67 | const queryString = QueryString.parse(querystring);
68 | log.info(config.CALLBACK_PATH);
69 | log.info(request.uri);
70 | if (request.uri.startsWith(config.CALLBACK_PATH)) {
71 | // log.info('callback from OIDC provider received');
72 | if (queryString.error) {
73 | return handleInvalidQueryString(queryString);
74 | }
75 | log.info(queryString.code);
76 | if (queryString.code === undefined || queryString.code === null) {
77 | return getUnauthorizedPayload('No Code Found', '', '');
78 | }
79 | return getNewJwtResponse({ evt, request, queryString, headers });
80 | }
81 | if ('cookie' in headers && 'TOKEN' in Cookie.parse(headers.cookie[0].value)) {
82 | return getVerifyJwtResponse(request, headers);
83 | } // log.info('redirecting to OIDC provider');
84 | return getOidcRedirectPayload(request, headers);
85 | }
86 |
87 | // getVerifyJwtResponse gets the appropriate response for verified Jwt.
88 | async function getVerifyJwtResponse(request, headers) {
89 | // log.info('request received with TOKEN cookie', { request, headers });
90 | try {
91 | // log.info('verifying JWT Response');
92 | await verifyJwt(Cookie.parse(headers.cookie[0].value).TOKEN, config.PUBLIC_KEY.trim(), {
93 | algorithms: ['RS256']
94 | }); // log.info('verified JWT Response');
95 | return request;
96 | } catch (err) {
97 | switch (err.name) {
98 | case 'TokenExpiredError':
99 | log.warn('token expired, redirecting to OIDC provider', undefined, err);
100 | return getOidcRedirectPayload(request, headers);
101 | case 'JsonWebTokenError':
102 | log.warn('jwt error, unauthorized', undefined, err);
103 | return getUnauthorizedPayload('Json Web Token Error', err.message, '');
104 | default:
105 | log.warn('unknown JWT error, unauthorized', undefined, err);
106 | return getUnauthorizedPayload('Unauthorized.', `User is not permitted`, '');
107 | }
108 | }
109 | }
110 |
111 | // getNewJwtResponse returns the response required to redirect and get a new Jwt.
112 | async function getNewJwtResponse({ evt, request, queryString, headers }) {
113 | try {
114 | config.TOKEN_REQUEST.code = queryString.code; // log.info('details', { config, queryString });
115 | const { idToken, decodedToken } = await getIdAndDecodedToken(); // log.info('searching for JWK from discovery document', { jwks, decodedToken, idToken });
116 | const rawPem = jwks.keys.filter((k) => k.kid === decodedToken.header.kid)[0];
117 | if (rawPem === undefined) {
118 | throw new Error('unable to find expected pem in jwks keys');
119 | }
120 | const pem = JwkToPem(rawPem); // log.info('verifying JWT', { rawPem, pem });
121 | try {
122 | const decoded = await verifyJwt(idToken, pem, { algorithms: ['RS256'] }); // log.info('decoded Jwt', { decoded });
123 | if (
124 | 'cookie' in headers &&
125 | 'NONCE' in Cookie.parse(headers.cookie[0].value) &&
126 | validateNonce(decoded.nonce, Cookie.parse(headers.cookie[0].value).NONCE)
127 | ) {
128 | return getRedirectPayload({ evt, queryString, decodedToken, headers });
129 | }
130 | return getUnauthorizedPayload('Nonce Verification Failed', '', '');
131 | } catch (err) {
132 | if (err === undefined || err === null || err.name === undefined || err.name === null) {
133 | log.warn('unknown named JWT error, unauthorized.', undefined, err);
134 | return getUnauthorizedPayload(
135 | 'Unknown JWT',
136 | `User ${decodedToken.payload.email || 'user'} is not permitted`,
137 | ''
138 | );
139 | }
140 | switch (err.name) {
141 | case 'TokenExpiredError':
142 | log.warn('token expired, redirecting to OIDC provider', undefined, err);
143 | return getOidcRedirectPayload(request, headers);
144 | case 'JsonWebTokenError':
145 | log.warn('jwt error, unauthorized', undefined, err);
146 | return getUnauthorizedPayload('Json Web Token Error', err.message, '');
147 | default:
148 | log.warn('unknown JWT error, unauthorized', undefined, err);
149 | return getUnauthorizedPayload(
150 | 'Unknown JWT',
151 | `User ${decodedToken.payload.email || 'user'} is not permitted`,
152 | ''
153 | );
154 | }
155 | }
156 | } catch (error) {
157 | log.error('internal server error', undefined, error);
158 | return getInternalServerErrorPayload();
159 | }
160 | }
161 |
162 | // getIdAndDecodedToken gets the id token and decoded version fo the token from the token
163 | // endpoint.
164 | async function getIdAndDecodedToken() {
165 | const tokenRequest = QueryString.stringify(config.TOKEN_REQUEST); // log.info('requesting access token.', { discoveryDocument, tokenRequest, config });
166 | const response = await deps.axios.post(discoveryDocument.token_endpoint, tokenRequest); // log.info('response', { response });
167 | const decodedToken = JsonWebToken.decode(response.data.id_token, {
168 | complete: true
169 | }); // log.info('decodedToken', { decodedToken });
170 | return { idToken: response.data.id_token, decodedToken };
171 | }
172 |
173 | // verifyJwt wraps the callback-based JsonWebToken.verify function in a promise.
174 | async function verifyJwt(token, pem, algorithms) {
175 | return new Promise((resolve, reject) => {
176 | JsonWebToken.verify(token, pem, algorithms, (err, decoded) => {
177 | if (err) {
178 | log.error('verifyJwt failed', { token, pem, algorithms }, err);
179 | return reject(err);
180 | }
181 | return resolve(decoded);
182 | });
183 | });
184 | }
185 |
186 | // handleInvalidQueryString creates an unauthorized response with the proper formatting when
187 | // a querysting contains an error.
188 | function handleInvalidQueryString(queryString) {
189 | const errors = {
190 | invalid_request: 'Invalid Request',
191 | unauthorized_client: 'Unauthorized Client',
192 | access_denied: 'Access Denied',
193 | unsupported_response_type: 'Unsupported Response Type',
194 | invalid_scope: 'Invalid Scope',
195 | server_error: 'Server Error',
196 | temporarily_unavailable: 'Temporarily Unavailable'
197 | };
198 |
199 | let error = '';
200 | let errorDescription = '';
201 | let errorUri = '';
202 |
203 | if (errors[queryString.error] != null) {
204 | error = errors[queryString.error];
205 | } else {
206 | error = queryString.error;
207 | }
208 | if (queryString.error_description != null) {
209 | errorDescription = queryString.error_description;
210 | } else {
211 | errorDescription = '';
212 | }
213 |
214 | if (queryString.error_uri != null) {
215 | errorUri = queryString.error_uri;
216 | } else {
217 | errorUri = '';
218 | }
219 |
220 | return getUnauthorizedPayload(error, errorDescription, errorUri);
221 | }
222 |
223 | // getNonceAndHash gets a nonce and hash.
224 | function getNonceAndHash() {
225 | const nonce = Crypto.randomBytes(32).toString('hex');
226 | const hash = Crypto.createHmac('sha256', nonce).digest('hex');
227 | return { nonce, hash };
228 | }
229 |
230 | // validateNonce validates a nonce.
231 | function validateNonce(nonce, hash) {
232 | const other = Crypto.createHmac('sha256', nonce).digest('hex');
233 | return other === hash;
234 | }
235 |
236 | // fetchConfigFromSecretsManager pulls the specified configuration from SecretsManager
237 | async function fetchConfigFromSecretsManager(evt) {
238 | // Get Secrets Manager Config Key from File since we cannot use environment variables.
239 | if (secretId == undefined) {
240 | try {
241 | secretId = "cloudfront/" + evt.Records[0].cf.config.distributionId;
242 | } catch (err) {
243 | log.error(err);
244 | }
245 | }
246 | const secret = await deps.sm.getSecretValue({ SecretId: secretId }); // eslint-disable-next-line no-buffer-constructor
247 | const buff = Buffer.from(JSON.parse(secret.SecretString).config, 'base64');
248 | const decodedval = JSON.parse(buff.toString('utf-8'));
249 | return decodedval;
250 | }
251 |
252 | // setConfig sets the config object to the value from SecretsManager if it wasn't already set.
253 | async function setConfig(event) {
254 | if (config === undefined) {
255 | config = await fetchConfigFromSecretsManager(event);
256 | }
257 |
258 | // set PKCE values if client_secret is not present in configurations
259 | if (config.TOKEN_REQUEST.client_secret == undefined){
260 | config.AUTH_REQUEST.code_challenge_method = "S256";
261 | config.AUTH_REQUEST.code_challenge = pkceCodeChallenge;
262 | config.AUTH_REQUEST.state = "state";
263 | config.TOKEN_REQUEST.code_verifier = pkceCodeVerifier;
264 | }
265 | }
266 |
267 | // setDiscoveryDocument sets the discoveryDocument object if it wasn't already set.
268 | async function setDiscoveryDocument() {
269 | if (discoveryDocument === undefined) {
270 | discoveryDocument = (await deps.axios.get(config.DISCOVERY_DOCUMENT)).data;
271 | }
272 | }
273 |
274 | // setJwks sets the jwks object if it wasn't already set.
275 | async function setJwks() {
276 | if (jwks === undefined) {
277 | if (
278 | discoveryDocument &&
279 | (discoveryDocument.jwks_uri === undefined || discoveryDocument.jwks_uri === null)
280 | ) {
281 | throw new Error('Unable to find JWK in discovery document');
282 | }
283 | jwks = (await deps.axios.get(discoveryDocument.jwks_uri)).data;
284 | }
285 | }
286 |
287 | function generatePkceCodeVerifier(size = 43) {
288 | return Crypto
289 | .randomBytes(size)
290 | .toString('hex')
291 | .slice(0, size)
292 | }
293 |
294 | function generatePkceCodeChallenge(codeVerifier){
295 | var hash = Crypto.createHash('sha256').update(codeVerifier).digest();
296 | return Base64Url.encode(hash);
297 | }
298 |
299 | // sets PKCE code verifier and code challenge values
300 | async function setPkceConfigs() {
301 | if (pkceCodeChallenge == undefined || pkceCodeVerifier == undefined) {
302 | pkceCodeVerifier = generatePkceCodeVerifier();
303 | pkceCodeChallenge = generatePkceCodeChallenge(pkceCodeVerifier);
304 | }
305 |
306 | }
307 |
308 | // prepareConfigGlobals sets up all the lambda globals if they are not already set.
309 | async function prepareConfigGlobals(event) {
310 | await setPkceConfigs();
311 | await setConfig(event);
312 | await setDiscoveryDocument();
313 | await setJwks();
314 | }
315 |
316 | // getRedirectPayload gets the actual 302 redirect payload
317 | function getRedirectPayload({ evt, queryString, decodedToken, headers }) {
318 | const response = {
319 | status: '302',
320 | statusDescription: 'Found',
321 | body: 'ID token retrieved.',
322 | headers: {
323 | location: [
324 | {
325 | key: 'Location',
326 | value:
327 | evt.Records[0].cf.config.test !== undefined
328 | ? config.AUTH_REQUEST.redirect_uri + queryString.state
329 | : queryString.state
330 | }
331 | ],
332 | 'login': [ { key: 'login', value: decodedToken.payload.email } ],
333 | 'set-cookie': [
334 | {
335 | key: 'Set-Cookie',
336 | value: Cookie.serialize(
337 | 'TOKEN',
338 | JsonWebToken.sign({}, config.PRIVATE_KEY.trim(), {
339 | audience: headers.host[0].value,
340 | subject: decodedToken.payload.email,
341 | expiresIn: config.SESSION_DURATION,
342 | algorithm: 'RS256'
343 | }),
344 | {
345 | path: '/',
346 | maxAge: config.SESSION_DURATION
347 | }
348 | )
349 | },
350 | {
351 | key: 'Set-Cookie',
352 | value: Cookie.serialize('NONCE', '', {
353 | path: '/',
354 | expires: new Date(1970, 1, 1, 0, 0, 0, 0)
355 | })
356 | }
357 | ]
358 | }
359 | }; // log.info('setting cookie and redirecting', { response });
360 | return response;
361 | }
362 |
363 | // redirect generates an appropriate redirect response.
364 | function getOidcRedirectPayload(request) {
365 | const { nonce, hash } = getNonceAndHash();
366 | config.AUTH_REQUEST.nonce = nonce;
367 | config.AUTH_REQUEST.state = request.uri; // Redirect to Authorization Server
368 |
369 | return {
370 | status: '302',
371 | statusDescription: 'Found',
372 | body: 'Redirecting to OIDC provider',
373 | headers: {
374 | location: [
375 | {
376 | key: 'Location',
377 | value: `${discoveryDocument.authorization_endpoint}?${QueryString.stringify(
378 | config.AUTH_REQUEST
379 | )}`
380 | }
381 | ],
382 | 'set-cookie': [
383 | {
384 | key: 'Set-Cookie',
385 | value: Cookie.serialize('TOKEN', '', {
386 | path: '/',
387 | expires: new Date(1970, 1, 1, 0, 0, 0, 0)
388 | })
389 | },
390 | {
391 | key: 'Set-Cookie',
392 | value: Cookie.serialize('NONCE', hash, {
393 | path: '/',
394 | httpOnly: true
395 | })
396 | }
397 | ]
398 | }
399 | };
400 | }
401 |
402 | // getUnauthorizedPayload generates an appropriate unauthorized response.
403 | function getUnauthorizedPayload(error, errorDescription, errorUri) {
404 | const body = `
405 |
406 |
407 |
408 |
409 | We've got some trouble | 401 - Unauthorized
410 |
411 |
412 |
413 | Unauthorized
Error 401Unauthorized
Unauthorized
414 |
415 |
416 |
417 | `;
418 |
419 | return {
420 | body,
421 | status: '401',
422 | statusDescription: 'Unauthorized',
423 | headers: {
424 | 'set-cookie': [
425 | {
426 | key: 'Set-Cookie',
427 | value: Cookie.serialize('TOKEN', '', {
428 | path: '/',
429 | expires: new Date(1970, 1, 1, 0, 0, 0, 0)
430 | })
431 | },
432 | {
433 | key: 'Set-Cookie',
434 | value: Cookie.serialize('NONCE', '', {
435 | path: '/',
436 | expires: new Date(1970, 1, 1, 0, 0, 0, 0)
437 | })
438 | }
439 | ]
440 | }
441 | };
442 | }
443 |
444 | // getInternalServerErrorPayload returns an appropriate InternalServerError response.
445 | function getInternalServerErrorPayload() {
446 | const body = `
447 |
448 |
449 |
450 |
451 | We've got some trouble | 500 - Internal Server Error
452 |
453 |
454 |
455 | Internal Server Error Error 500
456 |
457 |
458 | `;
459 |
460 | return { status: '500', statusDescription: 'Internal Server Error', body };
461 | }
462 |
--------------------------------------------------------------------------------
/src/js/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lambdaedge-openidconnect-samples",
3 | "version": "0.1.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "lambdaedge-openidconnect-samples",
9 | "version": "0.1.0",
10 | "license": "UNLICENSED",
11 | "dependencies": {
12 | "axios": "^1.6.2",
13 | "base64url": "^3.0.1",
14 | "cookie": "^0.3.1",
15 | "jsonwebtoken": "^9.0.0",
16 | "jwk-to-pem": "^1.2.6"
17 | },
18 | "devDependencies": {
19 | "depcheck": "^1.4.7"
20 | }
21 | },
22 | "node_modules/@babel/code-frame": {
23 | "version": "7.23.5",
24 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
25 | "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
26 | "dev": true,
27 | "dependencies": {
28 | "@babel/highlight": "^7.23.4",
29 | "chalk": "^2.4.2"
30 | },
31 | "engines": {
32 | "node": ">=6.9.0"
33 | }
34 | },
35 | "node_modules/@babel/generator": {
36 | "version": "7.23.6",
37 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
38 | "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
39 | "dev": true,
40 | "dependencies": {
41 | "@babel/types": "^7.23.6",
42 | "@jridgewell/gen-mapping": "^0.3.2",
43 | "@jridgewell/trace-mapping": "^0.3.17",
44 | "jsesc": "^2.5.1"
45 | },
46 | "engines": {
47 | "node": ">=6.9.0"
48 | }
49 | },
50 | "node_modules/@babel/helper-environment-visitor": {
51 | "version": "7.22.20",
52 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
53 | "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
54 | "dev": true,
55 | "engines": {
56 | "node": ">=6.9.0"
57 | }
58 | },
59 | "node_modules/@babel/helper-function-name": {
60 | "version": "7.23.0",
61 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
62 | "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
63 | "dev": true,
64 | "dependencies": {
65 | "@babel/template": "^7.22.15",
66 | "@babel/types": "^7.23.0"
67 | },
68 | "engines": {
69 | "node": ">=6.9.0"
70 | }
71 | },
72 | "node_modules/@babel/helper-hoist-variables": {
73 | "version": "7.22.5",
74 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
75 | "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
76 | "dev": true,
77 | "dependencies": {
78 | "@babel/types": "^7.22.5"
79 | },
80 | "engines": {
81 | "node": ">=6.9.0"
82 | }
83 | },
84 | "node_modules/@babel/helper-split-export-declaration": {
85 | "version": "7.22.6",
86 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
87 | "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
88 | "dev": true,
89 | "dependencies": {
90 | "@babel/types": "^7.22.5"
91 | },
92 | "engines": {
93 | "node": ">=6.9.0"
94 | }
95 | },
96 | "node_modules/@babel/helper-string-parser": {
97 | "version": "7.23.4",
98 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
99 | "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
100 | "dev": true,
101 | "engines": {
102 | "node": ">=6.9.0"
103 | }
104 | },
105 | "node_modules/@babel/helper-validator-identifier": {
106 | "version": "7.22.20",
107 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
108 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
109 | "dev": true,
110 | "engines": {
111 | "node": ">=6.9.0"
112 | }
113 | },
114 | "node_modules/@babel/highlight": {
115 | "version": "7.23.4",
116 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
117 | "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
118 | "dev": true,
119 | "dependencies": {
120 | "@babel/helper-validator-identifier": "^7.22.20",
121 | "chalk": "^2.4.2",
122 | "js-tokens": "^4.0.0"
123 | },
124 | "engines": {
125 | "node": ">=6.9.0"
126 | }
127 | },
128 | "node_modules/@babel/parser": {
129 | "version": "7.23.6",
130 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
131 | "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
132 | "dev": true,
133 | "bin": {
134 | "parser": "bin/babel-parser.js"
135 | },
136 | "engines": {
137 | "node": ">=6.0.0"
138 | }
139 | },
140 | "node_modules/@babel/template": {
141 | "version": "7.22.15",
142 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
143 | "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
144 | "dev": true,
145 | "dependencies": {
146 | "@babel/code-frame": "^7.22.13",
147 | "@babel/parser": "^7.22.15",
148 | "@babel/types": "^7.22.15"
149 | },
150 | "engines": {
151 | "node": ">=6.9.0"
152 | }
153 | },
154 | "node_modules/@babel/traverse": {
155 | "version": "7.23.7",
156 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
157 | "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
158 | "dev": true,
159 | "dependencies": {
160 | "@babel/code-frame": "^7.23.5",
161 | "@babel/generator": "^7.23.6",
162 | "@babel/helper-environment-visitor": "^7.22.20",
163 | "@babel/helper-function-name": "^7.23.0",
164 | "@babel/helper-hoist-variables": "^7.22.5",
165 | "@babel/helper-split-export-declaration": "^7.22.6",
166 | "@babel/parser": "^7.23.6",
167 | "@babel/types": "^7.23.6",
168 | "debug": "^4.3.1",
169 | "globals": "^11.1.0"
170 | },
171 | "engines": {
172 | "node": ">=6.9.0"
173 | }
174 | },
175 | "node_modules/@babel/types": {
176 | "version": "7.23.6",
177 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
178 | "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
179 | "dev": true,
180 | "dependencies": {
181 | "@babel/helper-string-parser": "^7.23.4",
182 | "@babel/helper-validator-identifier": "^7.22.20",
183 | "to-fast-properties": "^2.0.0"
184 | },
185 | "engines": {
186 | "node": ">=6.9.0"
187 | }
188 | },
189 | "node_modules/@jridgewell/gen-mapping": {
190 | "version": "0.3.3",
191 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
192 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
193 | "dev": true,
194 | "dependencies": {
195 | "@jridgewell/set-array": "^1.0.1",
196 | "@jridgewell/sourcemap-codec": "^1.4.10",
197 | "@jridgewell/trace-mapping": "^0.3.9"
198 | },
199 | "engines": {
200 | "node": ">=6.0.0"
201 | }
202 | },
203 | "node_modules/@jridgewell/resolve-uri": {
204 | "version": "3.1.1",
205 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
206 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
207 | "dev": true,
208 | "engines": {
209 | "node": ">=6.0.0"
210 | }
211 | },
212 | "node_modules/@jridgewell/set-array": {
213 | "version": "1.1.2",
214 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
215 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
216 | "dev": true,
217 | "engines": {
218 | "node": ">=6.0.0"
219 | }
220 | },
221 | "node_modules/@jridgewell/sourcemap-codec": {
222 | "version": "1.4.15",
223 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
224 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
225 | "dev": true
226 | },
227 | "node_modules/@jridgewell/trace-mapping": {
228 | "version": "0.3.22",
229 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
230 | "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
231 | "dev": true,
232 | "dependencies": {
233 | "@jridgewell/resolve-uri": "^3.1.0",
234 | "@jridgewell/sourcemap-codec": "^1.4.14"
235 | }
236 | },
237 | "node_modules/@types/minimatch": {
238 | "version": "3.0.5",
239 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
240 | "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
241 | "dev": true
242 | },
243 | "node_modules/@types/parse-json": {
244 | "version": "4.0.2",
245 | "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
246 | "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
247 | "dev": true
248 | },
249 | "node_modules/@vue/compiler-core": {
250 | "version": "3.4.15",
251 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz",
252 | "integrity": "sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==",
253 | "dev": true,
254 | "dependencies": {
255 | "@babel/parser": "^7.23.6",
256 | "@vue/shared": "3.4.15",
257 | "entities": "^4.5.0",
258 | "estree-walker": "^2.0.2",
259 | "source-map-js": "^1.0.2"
260 | }
261 | },
262 | "node_modules/@vue/compiler-dom": {
263 | "version": "3.4.15",
264 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz",
265 | "integrity": "sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==",
266 | "dev": true,
267 | "dependencies": {
268 | "@vue/compiler-core": "3.4.15",
269 | "@vue/shared": "3.4.15"
270 | }
271 | },
272 | "node_modules/@vue/compiler-sfc": {
273 | "version": "3.4.15",
274 | "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz",
275 | "integrity": "sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==",
276 | "dev": true,
277 | "dependencies": {
278 | "@babel/parser": "^7.23.6",
279 | "@vue/compiler-core": "3.4.15",
280 | "@vue/compiler-dom": "3.4.15",
281 | "@vue/compiler-ssr": "3.4.15",
282 | "@vue/shared": "3.4.15",
283 | "estree-walker": "^2.0.2",
284 | "magic-string": "^0.30.5",
285 | "postcss": "^8.4.33",
286 | "source-map-js": "^1.0.2"
287 | }
288 | },
289 | "node_modules/@vue/compiler-ssr": {
290 | "version": "3.4.15",
291 | "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz",
292 | "integrity": "sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==",
293 | "dev": true,
294 | "dependencies": {
295 | "@vue/compiler-dom": "3.4.15",
296 | "@vue/shared": "3.4.15"
297 | }
298 | },
299 | "node_modules/@vue/shared": {
300 | "version": "3.4.15",
301 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz",
302 | "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==",
303 | "dev": true
304 | },
305 | "node_modules/ansi-regex": {
306 | "version": "5.0.1",
307 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
308 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
309 | "dev": true,
310 | "engines": {
311 | "node": ">=8"
312 | }
313 | },
314 | "node_modules/ansi-styles": {
315 | "version": "3.2.1",
316 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
317 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
318 | "dev": true,
319 | "dependencies": {
320 | "color-convert": "^1.9.0"
321 | },
322 | "engines": {
323 | "node": ">=4"
324 | }
325 | },
326 | "node_modules/argparse": {
327 | "version": "1.0.10",
328 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
329 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
330 | "dev": true,
331 | "dependencies": {
332 | "sprintf-js": "~1.0.2"
333 | }
334 | },
335 | "node_modules/array-differ": {
336 | "version": "3.0.0",
337 | "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
338 | "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
339 | "dev": true,
340 | "engines": {
341 | "node": ">=8"
342 | }
343 | },
344 | "node_modules/array-union": {
345 | "version": "2.1.0",
346 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
347 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
348 | "dev": true,
349 | "engines": {
350 | "node": ">=8"
351 | }
352 | },
353 | "node_modules/arrify": {
354 | "version": "2.0.1",
355 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
356 | "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
357 | "dev": true,
358 | "engines": {
359 | "node": ">=8"
360 | }
361 | },
362 | "node_modules/asn1.js": {
363 | "version": "4.10.1",
364 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
365 | "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
366 | "dependencies": {
367 | "bn.js": "^4.0.0",
368 | "inherits": "^2.0.1",
369 | "minimalistic-assert": "^1.0.0"
370 | }
371 | },
372 | "node_modules/asynckit": {
373 | "version": "0.4.0",
374 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
375 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
376 | },
377 | "node_modules/axios": {
378 | "version": "1.6.5",
379 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz",
380 | "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==",
381 | "dependencies": {
382 | "follow-redirects": "^1.15.4",
383 | "form-data": "^4.0.0",
384 | "proxy-from-env": "^1.1.0"
385 | }
386 | },
387 | "node_modules/balanced-match": {
388 | "version": "1.0.2",
389 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
390 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
391 | "dev": true
392 | },
393 | "node_modules/base64url": {
394 | "version": "3.0.1",
395 | "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
396 | "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==",
397 | "engines": {
398 | "node": ">=6.0.0"
399 | }
400 | },
401 | "node_modules/bn.js": {
402 | "version": "4.12.0",
403 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
404 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
405 | },
406 | "node_modules/brace-expansion": {
407 | "version": "2.0.1",
408 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
409 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
410 | "dev": true,
411 | "dependencies": {
412 | "balanced-match": "^1.0.0"
413 | }
414 | },
415 | "node_modules/braces": {
416 | "version": "3.0.2",
417 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
418 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
419 | "dev": true,
420 | "dependencies": {
421 | "fill-range": "^7.0.1"
422 | },
423 | "engines": {
424 | "node": ">=8"
425 | }
426 | },
427 | "node_modules/brorand": {
428 | "version": "1.1.0",
429 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
430 | "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w=="
431 | },
432 | "node_modules/buffer-equal-constant-time": {
433 | "version": "1.0.1",
434 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
435 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
436 | },
437 | "node_modules/callsite": {
438 | "version": "1.0.0",
439 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
440 | "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==",
441 | "dev": true,
442 | "engines": {
443 | "node": "*"
444 | }
445 | },
446 | "node_modules/callsites": {
447 | "version": "3.1.0",
448 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
449 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
450 | "dev": true,
451 | "engines": {
452 | "node": ">=6"
453 | }
454 | },
455 | "node_modules/camelcase": {
456 | "version": "6.3.0",
457 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
458 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
459 | "dev": true,
460 | "engines": {
461 | "node": ">=10"
462 | },
463 | "funding": {
464 | "url": "https://github.com/sponsors/sindresorhus"
465 | }
466 | },
467 | "node_modules/chalk": {
468 | "version": "2.4.2",
469 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
470 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
471 | "dev": true,
472 | "dependencies": {
473 | "ansi-styles": "^3.2.1",
474 | "escape-string-regexp": "^1.0.5",
475 | "supports-color": "^5.3.0"
476 | },
477 | "engines": {
478 | "node": ">=4"
479 | }
480 | },
481 | "node_modules/cliui": {
482 | "version": "7.0.4",
483 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
484 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
485 | "dev": true,
486 | "dependencies": {
487 | "string-width": "^4.2.0",
488 | "strip-ansi": "^6.0.0",
489 | "wrap-ansi": "^7.0.0"
490 | }
491 | },
492 | "node_modules/color-convert": {
493 | "version": "1.9.3",
494 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
495 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
496 | "dev": true,
497 | "dependencies": {
498 | "color-name": "1.1.3"
499 | }
500 | },
501 | "node_modules/color-name": {
502 | "version": "1.1.3",
503 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
504 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
505 | "dev": true
506 | },
507 | "node_modules/combined-stream": {
508 | "version": "1.0.8",
509 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
510 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
511 | "dependencies": {
512 | "delayed-stream": "~1.0.0"
513 | },
514 | "engines": {
515 | "node": ">= 0.8"
516 | }
517 | },
518 | "node_modules/concat-map": {
519 | "version": "0.0.1",
520 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
521 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
522 | "dev": true
523 | },
524 | "node_modules/cookie": {
525 | "version": "0.3.1",
526 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
527 | "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==",
528 | "engines": {
529 | "node": ">= 0.6"
530 | }
531 | },
532 | "node_modules/cosmiconfig": {
533 | "version": "7.1.0",
534 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
535 | "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
536 | "dev": true,
537 | "dependencies": {
538 | "@types/parse-json": "^4.0.0",
539 | "import-fresh": "^3.2.1",
540 | "parse-json": "^5.0.0",
541 | "path-type": "^4.0.0",
542 | "yaml": "^1.10.0"
543 | },
544 | "engines": {
545 | "node": ">=10"
546 | }
547 | },
548 | "node_modules/debug": {
549 | "version": "4.3.4",
550 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
551 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
552 | "dev": true,
553 | "dependencies": {
554 | "ms": "2.1.2"
555 | },
556 | "engines": {
557 | "node": ">=6.0"
558 | },
559 | "peerDependenciesMeta": {
560 | "supports-color": {
561 | "optional": true
562 | }
563 | }
564 | },
565 | "node_modules/delayed-stream": {
566 | "version": "1.0.0",
567 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
568 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
569 | "engines": {
570 | "node": ">=0.4.0"
571 | }
572 | },
573 | "node_modules/depcheck": {
574 | "version": "1.4.7",
575 | "resolved": "https://registry.npmjs.org/depcheck/-/depcheck-1.4.7.tgz",
576 | "integrity": "sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==",
577 | "dev": true,
578 | "dependencies": {
579 | "@babel/parser": "^7.23.0",
580 | "@babel/traverse": "^7.23.2",
581 | "@vue/compiler-sfc": "^3.3.4",
582 | "callsite": "^1.0.0",
583 | "camelcase": "^6.3.0",
584 | "cosmiconfig": "^7.1.0",
585 | "debug": "^4.3.4",
586 | "deps-regex": "^0.2.0",
587 | "findup-sync": "^5.0.0",
588 | "ignore": "^5.2.4",
589 | "is-core-module": "^2.12.0",
590 | "js-yaml": "^3.14.1",
591 | "json5": "^2.2.3",
592 | "lodash": "^4.17.21",
593 | "minimatch": "^7.4.6",
594 | "multimatch": "^5.0.0",
595 | "please-upgrade-node": "^3.2.0",
596 | "readdirp": "^3.6.0",
597 | "require-package-name": "^2.0.1",
598 | "resolve": "^1.22.3",
599 | "resolve-from": "^5.0.0",
600 | "semver": "^7.5.4",
601 | "yargs": "^16.2.0"
602 | },
603 | "bin": {
604 | "depcheck": "bin/depcheck.js"
605 | },
606 | "engines": {
607 | "node": ">=10"
608 | }
609 | },
610 | "node_modules/deps-regex": {
611 | "version": "0.2.0",
612 | "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.2.0.tgz",
613 | "integrity": "sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==",
614 | "dev": true
615 | },
616 | "node_modules/detect-file": {
617 | "version": "1.0.0",
618 | "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
619 | "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
620 | "dev": true,
621 | "engines": {
622 | "node": ">=0.10.0"
623 | }
624 | },
625 | "node_modules/ecdsa-sig-formatter": {
626 | "version": "1.0.11",
627 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
628 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
629 | "dependencies": {
630 | "safe-buffer": "^5.0.1"
631 | }
632 | },
633 | "node_modules/elliptic": {
634 | "version": "6.5.4",
635 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
636 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
637 | "dependencies": {
638 | "bn.js": "^4.11.9",
639 | "brorand": "^1.1.0",
640 | "hash.js": "^1.0.0",
641 | "hmac-drbg": "^1.0.1",
642 | "inherits": "^2.0.4",
643 | "minimalistic-assert": "^1.0.1",
644 | "minimalistic-crypto-utils": "^1.0.1"
645 | }
646 | },
647 | "node_modules/emoji-regex": {
648 | "version": "8.0.0",
649 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
650 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
651 | "dev": true
652 | },
653 | "node_modules/entities": {
654 | "version": "4.5.0",
655 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
656 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
657 | "dev": true,
658 | "engines": {
659 | "node": ">=0.12"
660 | },
661 | "funding": {
662 | "url": "https://github.com/fb55/entities?sponsor=1"
663 | }
664 | },
665 | "node_modules/error-ex": {
666 | "version": "1.3.2",
667 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
668 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
669 | "dev": true,
670 | "dependencies": {
671 | "is-arrayish": "^0.2.1"
672 | }
673 | },
674 | "node_modules/escalade": {
675 | "version": "3.1.1",
676 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
677 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
678 | "dev": true,
679 | "engines": {
680 | "node": ">=6"
681 | }
682 | },
683 | "node_modules/escape-string-regexp": {
684 | "version": "1.0.5",
685 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
686 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
687 | "dev": true,
688 | "engines": {
689 | "node": ">=0.8.0"
690 | }
691 | },
692 | "node_modules/esprima": {
693 | "version": "4.0.1",
694 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
695 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
696 | "dev": true,
697 | "bin": {
698 | "esparse": "bin/esparse.js",
699 | "esvalidate": "bin/esvalidate.js"
700 | },
701 | "engines": {
702 | "node": ">=4"
703 | }
704 | },
705 | "node_modules/estree-walker": {
706 | "version": "2.0.2",
707 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
708 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
709 | "dev": true
710 | },
711 | "node_modules/expand-tilde": {
712 | "version": "2.0.2",
713 | "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
714 | "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
715 | "dev": true,
716 | "dependencies": {
717 | "homedir-polyfill": "^1.0.1"
718 | },
719 | "engines": {
720 | "node": ">=0.10.0"
721 | }
722 | },
723 | "node_modules/fill-range": {
724 | "version": "7.0.1",
725 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
726 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
727 | "dev": true,
728 | "dependencies": {
729 | "to-regex-range": "^5.0.1"
730 | },
731 | "engines": {
732 | "node": ">=8"
733 | }
734 | },
735 | "node_modules/findup-sync": {
736 | "version": "5.0.0",
737 | "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
738 | "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
739 | "dev": true,
740 | "dependencies": {
741 | "detect-file": "^1.0.0",
742 | "is-glob": "^4.0.3",
743 | "micromatch": "^4.0.4",
744 | "resolve-dir": "^1.0.1"
745 | },
746 | "engines": {
747 | "node": ">= 10.13.0"
748 | }
749 | },
750 | "node_modules/follow-redirects": {
751 | "version": "1.15.5",
752 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
753 | "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
754 | "funding": [
755 | {
756 | "type": "individual",
757 | "url": "https://github.com/sponsors/RubenVerborgh"
758 | }
759 | ],
760 | "engines": {
761 | "node": ">=4.0"
762 | },
763 | "peerDependenciesMeta": {
764 | "debug": {
765 | "optional": true
766 | }
767 | }
768 | },
769 | "node_modules/form-data": {
770 | "version": "4.0.0",
771 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
772 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
773 | "dependencies": {
774 | "asynckit": "^0.4.0",
775 | "combined-stream": "^1.0.8",
776 | "mime-types": "^2.1.12"
777 | },
778 | "engines": {
779 | "node": ">= 6"
780 | }
781 | },
782 | "node_modules/function-bind": {
783 | "version": "1.1.2",
784 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
785 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
786 | "dev": true,
787 | "funding": {
788 | "url": "https://github.com/sponsors/ljharb"
789 | }
790 | },
791 | "node_modules/get-caller-file": {
792 | "version": "2.0.5",
793 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
794 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
795 | "dev": true,
796 | "engines": {
797 | "node": "6.* || 8.* || >= 10.*"
798 | }
799 | },
800 | "node_modules/global-modules": {
801 | "version": "1.0.0",
802 | "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
803 | "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
804 | "dev": true,
805 | "dependencies": {
806 | "global-prefix": "^1.0.1",
807 | "is-windows": "^1.0.1",
808 | "resolve-dir": "^1.0.0"
809 | },
810 | "engines": {
811 | "node": ">=0.10.0"
812 | }
813 | },
814 | "node_modules/global-prefix": {
815 | "version": "1.0.2",
816 | "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
817 | "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
818 | "dev": true,
819 | "dependencies": {
820 | "expand-tilde": "^2.0.2",
821 | "homedir-polyfill": "^1.0.1",
822 | "ini": "^1.3.4",
823 | "is-windows": "^1.0.1",
824 | "which": "^1.2.14"
825 | },
826 | "engines": {
827 | "node": ">=0.10.0"
828 | }
829 | },
830 | "node_modules/globals": {
831 | "version": "11.12.0",
832 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
833 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
834 | "dev": true,
835 | "engines": {
836 | "node": ">=4"
837 | }
838 | },
839 | "node_modules/has-flag": {
840 | "version": "3.0.0",
841 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
842 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
843 | "dev": true,
844 | "engines": {
845 | "node": ">=4"
846 | }
847 | },
848 | "node_modules/hash.js": {
849 | "version": "1.1.7",
850 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
851 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
852 | "dependencies": {
853 | "inherits": "^2.0.3",
854 | "minimalistic-assert": "^1.0.1"
855 | }
856 | },
857 | "node_modules/hasown": {
858 | "version": "2.0.0",
859 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
860 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
861 | "dev": true,
862 | "dependencies": {
863 | "function-bind": "^1.1.2"
864 | },
865 | "engines": {
866 | "node": ">= 0.4"
867 | }
868 | },
869 | "node_modules/hmac-drbg": {
870 | "version": "1.0.1",
871 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
872 | "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
873 | "dependencies": {
874 | "hash.js": "^1.0.3",
875 | "minimalistic-assert": "^1.0.0",
876 | "minimalistic-crypto-utils": "^1.0.1"
877 | }
878 | },
879 | "node_modules/homedir-polyfill": {
880 | "version": "1.0.3",
881 | "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
882 | "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
883 | "dev": true,
884 | "dependencies": {
885 | "parse-passwd": "^1.0.0"
886 | },
887 | "engines": {
888 | "node": ">=0.10.0"
889 | }
890 | },
891 | "node_modules/ignore": {
892 | "version": "5.3.0",
893 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
894 | "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==",
895 | "dev": true,
896 | "engines": {
897 | "node": ">= 4"
898 | }
899 | },
900 | "node_modules/import-fresh": {
901 | "version": "3.3.0",
902 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
903 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
904 | "dev": true,
905 | "dependencies": {
906 | "parent-module": "^1.0.0",
907 | "resolve-from": "^4.0.0"
908 | },
909 | "engines": {
910 | "node": ">=6"
911 | },
912 | "funding": {
913 | "url": "https://github.com/sponsors/sindresorhus"
914 | }
915 | },
916 | "node_modules/import-fresh/node_modules/resolve-from": {
917 | "version": "4.0.0",
918 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
919 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
920 | "dev": true,
921 | "engines": {
922 | "node": ">=4"
923 | }
924 | },
925 | "node_modules/inherits": {
926 | "version": "2.0.4",
927 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
928 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
929 | },
930 | "node_modules/ini": {
931 | "version": "1.3.8",
932 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
933 | "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
934 | "dev": true
935 | },
936 | "node_modules/is-arrayish": {
937 | "version": "0.2.1",
938 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
939 | "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
940 | "dev": true
941 | },
942 | "node_modules/is-core-module": {
943 | "version": "2.13.1",
944 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
945 | "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
946 | "dev": true,
947 | "dependencies": {
948 | "hasown": "^2.0.0"
949 | },
950 | "funding": {
951 | "url": "https://github.com/sponsors/ljharb"
952 | }
953 | },
954 | "node_modules/is-extglob": {
955 | "version": "2.1.1",
956 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
957 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
958 | "dev": true,
959 | "engines": {
960 | "node": ">=0.10.0"
961 | }
962 | },
963 | "node_modules/is-fullwidth-code-point": {
964 | "version": "3.0.0",
965 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
966 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
967 | "dev": true,
968 | "engines": {
969 | "node": ">=8"
970 | }
971 | },
972 | "node_modules/is-glob": {
973 | "version": "4.0.3",
974 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
975 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
976 | "dev": true,
977 | "dependencies": {
978 | "is-extglob": "^2.1.1"
979 | },
980 | "engines": {
981 | "node": ">=0.10.0"
982 | }
983 | },
984 | "node_modules/is-number": {
985 | "version": "7.0.0",
986 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
987 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
988 | "dev": true,
989 | "engines": {
990 | "node": ">=0.12.0"
991 | }
992 | },
993 | "node_modules/is-windows": {
994 | "version": "1.0.2",
995 | "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
996 | "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
997 | "dev": true,
998 | "engines": {
999 | "node": ">=0.10.0"
1000 | }
1001 | },
1002 | "node_modules/isexe": {
1003 | "version": "2.0.0",
1004 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1005 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1006 | "dev": true
1007 | },
1008 | "node_modules/js-tokens": {
1009 | "version": "4.0.0",
1010 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1011 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1012 | "dev": true
1013 | },
1014 | "node_modules/js-yaml": {
1015 | "version": "3.14.1",
1016 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
1017 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
1018 | "dev": true,
1019 | "dependencies": {
1020 | "argparse": "^1.0.7",
1021 | "esprima": "^4.0.0"
1022 | },
1023 | "bin": {
1024 | "js-yaml": "bin/js-yaml.js"
1025 | }
1026 | },
1027 | "node_modules/jsesc": {
1028 | "version": "2.5.2",
1029 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
1030 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
1031 | "dev": true,
1032 | "bin": {
1033 | "jsesc": "bin/jsesc"
1034 | },
1035 | "engines": {
1036 | "node": ">=4"
1037 | }
1038 | },
1039 | "node_modules/json-parse-even-better-errors": {
1040 | "version": "2.3.1",
1041 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
1042 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
1043 | "dev": true
1044 | },
1045 | "node_modules/json5": {
1046 | "version": "2.2.3",
1047 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
1048 | "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
1049 | "dev": true,
1050 | "bin": {
1051 | "json5": "lib/cli.js"
1052 | },
1053 | "engines": {
1054 | "node": ">=6"
1055 | }
1056 | },
1057 | "node_modules/jsonwebtoken": {
1058 | "version": "9.0.2",
1059 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
1060 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
1061 | "dependencies": {
1062 | "jws": "^3.2.2",
1063 | "lodash.includes": "^4.3.0",
1064 | "lodash.isboolean": "^3.0.3",
1065 | "lodash.isinteger": "^4.0.4",
1066 | "lodash.isnumber": "^3.0.3",
1067 | "lodash.isplainobject": "^4.0.6",
1068 | "lodash.isstring": "^4.0.1",
1069 | "lodash.once": "^4.0.0",
1070 | "ms": "^2.1.1",
1071 | "semver": "^7.5.4"
1072 | },
1073 | "engines": {
1074 | "node": ">=12",
1075 | "npm": ">=6"
1076 | }
1077 | },
1078 | "node_modules/jwa": {
1079 | "version": "1.4.1",
1080 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
1081 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
1082 | "dependencies": {
1083 | "buffer-equal-constant-time": "1.0.1",
1084 | "ecdsa-sig-formatter": "1.0.11",
1085 | "safe-buffer": "^5.0.1"
1086 | }
1087 | },
1088 | "node_modules/jwk-to-pem": {
1089 | "version": "1.2.6",
1090 | "resolved": "https://registry.npmjs.org/jwk-to-pem/-/jwk-to-pem-1.2.6.tgz",
1091 | "integrity": "sha512-Ipnj4HJk49KJ6j8u6niB37f8waRf+9uDpJlnk9QRJbH2AIII2w59VoajS5s2V0MYfIS5s+Hys9G6dspJmLn95Q==",
1092 | "dependencies": {
1093 | "asn1.js": "^4.5.2",
1094 | "elliptic": "^6.2.3",
1095 | "safe-buffer": "^5.0.1"
1096 | }
1097 | },
1098 | "node_modules/jws": {
1099 | "version": "3.2.2",
1100 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
1101 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
1102 | "dependencies": {
1103 | "jwa": "^1.4.1",
1104 | "safe-buffer": "^5.0.1"
1105 | }
1106 | },
1107 | "node_modules/lines-and-columns": {
1108 | "version": "1.2.4",
1109 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
1110 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
1111 | "dev": true
1112 | },
1113 | "node_modules/lodash": {
1114 | "version": "4.17.21",
1115 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
1116 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
1117 | "dev": true
1118 | },
1119 | "node_modules/lodash.includes": {
1120 | "version": "4.3.0",
1121 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
1122 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
1123 | },
1124 | "node_modules/lodash.isboolean": {
1125 | "version": "3.0.3",
1126 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
1127 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
1128 | },
1129 | "node_modules/lodash.isinteger": {
1130 | "version": "4.0.4",
1131 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
1132 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
1133 | },
1134 | "node_modules/lodash.isnumber": {
1135 | "version": "3.0.3",
1136 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
1137 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
1138 | },
1139 | "node_modules/lodash.isplainobject": {
1140 | "version": "4.0.6",
1141 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
1142 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
1143 | },
1144 | "node_modules/lodash.isstring": {
1145 | "version": "4.0.1",
1146 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
1147 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
1148 | },
1149 | "node_modules/lodash.once": {
1150 | "version": "4.1.1",
1151 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
1152 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
1153 | },
1154 | "node_modules/lru-cache": {
1155 | "version": "6.0.0",
1156 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
1157 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
1158 | "dependencies": {
1159 | "yallist": "^4.0.0"
1160 | },
1161 | "engines": {
1162 | "node": ">=10"
1163 | }
1164 | },
1165 | "node_modules/magic-string": {
1166 | "version": "0.30.5",
1167 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
1168 | "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
1169 | "dev": true,
1170 | "dependencies": {
1171 | "@jridgewell/sourcemap-codec": "^1.4.15"
1172 | },
1173 | "engines": {
1174 | "node": ">=12"
1175 | }
1176 | },
1177 | "node_modules/micromatch": {
1178 | "version": "4.0.5",
1179 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
1180 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
1181 | "dev": true,
1182 | "dependencies": {
1183 | "braces": "^3.0.2",
1184 | "picomatch": "^2.3.1"
1185 | },
1186 | "engines": {
1187 | "node": ">=8.6"
1188 | }
1189 | },
1190 | "node_modules/mime-db": {
1191 | "version": "1.52.0",
1192 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1193 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1194 | "engines": {
1195 | "node": ">= 0.6"
1196 | }
1197 | },
1198 | "node_modules/mime-types": {
1199 | "version": "2.1.35",
1200 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1201 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1202 | "dependencies": {
1203 | "mime-db": "1.52.0"
1204 | },
1205 | "engines": {
1206 | "node": ">= 0.6"
1207 | }
1208 | },
1209 | "node_modules/minimalistic-assert": {
1210 | "version": "1.0.1",
1211 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
1212 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
1213 | },
1214 | "node_modules/minimalistic-crypto-utils": {
1215 | "version": "1.0.1",
1216 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
1217 | "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="
1218 | },
1219 | "node_modules/minimatch": {
1220 | "version": "7.4.6",
1221 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz",
1222 | "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==",
1223 | "dev": true,
1224 | "dependencies": {
1225 | "brace-expansion": "^2.0.1"
1226 | },
1227 | "engines": {
1228 | "node": ">=10"
1229 | },
1230 | "funding": {
1231 | "url": "https://github.com/sponsors/isaacs"
1232 | }
1233 | },
1234 | "node_modules/ms": {
1235 | "version": "2.1.2",
1236 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1237 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
1238 | },
1239 | "node_modules/multimatch": {
1240 | "version": "5.0.0",
1241 | "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz",
1242 | "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==",
1243 | "dev": true,
1244 | "dependencies": {
1245 | "@types/minimatch": "^3.0.3",
1246 | "array-differ": "^3.0.0",
1247 | "array-union": "^2.1.0",
1248 | "arrify": "^2.0.1",
1249 | "minimatch": "^3.0.4"
1250 | },
1251 | "engines": {
1252 | "node": ">=10"
1253 | },
1254 | "funding": {
1255 | "url": "https://github.com/sponsors/sindresorhus"
1256 | }
1257 | },
1258 | "node_modules/multimatch/node_modules/brace-expansion": {
1259 | "version": "1.1.11",
1260 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1261 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1262 | "dev": true,
1263 | "dependencies": {
1264 | "balanced-match": "^1.0.0",
1265 | "concat-map": "0.0.1"
1266 | }
1267 | },
1268 | "node_modules/multimatch/node_modules/minimatch": {
1269 | "version": "3.1.2",
1270 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1271 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1272 | "dev": true,
1273 | "dependencies": {
1274 | "brace-expansion": "^1.1.7"
1275 | },
1276 | "engines": {
1277 | "node": "*"
1278 | }
1279 | },
1280 | "node_modules/nanoid": {
1281 | "version": "3.3.7",
1282 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
1283 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
1284 | "dev": true,
1285 | "funding": [
1286 | {
1287 | "type": "github",
1288 | "url": "https://github.com/sponsors/ai"
1289 | }
1290 | ],
1291 | "bin": {
1292 | "nanoid": "bin/nanoid.cjs"
1293 | },
1294 | "engines": {
1295 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1296 | }
1297 | },
1298 | "node_modules/parent-module": {
1299 | "version": "1.0.1",
1300 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
1301 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
1302 | "dev": true,
1303 | "dependencies": {
1304 | "callsites": "^3.0.0"
1305 | },
1306 | "engines": {
1307 | "node": ">=6"
1308 | }
1309 | },
1310 | "node_modules/parse-json": {
1311 | "version": "5.2.0",
1312 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
1313 | "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
1314 | "dev": true,
1315 | "dependencies": {
1316 | "@babel/code-frame": "^7.0.0",
1317 | "error-ex": "^1.3.1",
1318 | "json-parse-even-better-errors": "^2.3.0",
1319 | "lines-and-columns": "^1.1.6"
1320 | },
1321 | "engines": {
1322 | "node": ">=8"
1323 | },
1324 | "funding": {
1325 | "url": "https://github.com/sponsors/sindresorhus"
1326 | }
1327 | },
1328 | "node_modules/parse-passwd": {
1329 | "version": "1.0.0",
1330 | "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
1331 | "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
1332 | "dev": true,
1333 | "engines": {
1334 | "node": ">=0.10.0"
1335 | }
1336 | },
1337 | "node_modules/path-parse": {
1338 | "version": "1.0.7",
1339 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1340 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1341 | "dev": true
1342 | },
1343 | "node_modules/path-type": {
1344 | "version": "4.0.0",
1345 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
1346 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
1347 | "dev": true,
1348 | "engines": {
1349 | "node": ">=8"
1350 | }
1351 | },
1352 | "node_modules/picocolors": {
1353 | "version": "1.0.0",
1354 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
1355 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
1356 | "dev": true
1357 | },
1358 | "node_modules/picomatch": {
1359 | "version": "2.3.1",
1360 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1361 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1362 | "dev": true,
1363 | "engines": {
1364 | "node": ">=8.6"
1365 | },
1366 | "funding": {
1367 | "url": "https://github.com/sponsors/jonschlinkert"
1368 | }
1369 | },
1370 | "node_modules/please-upgrade-node": {
1371 | "version": "3.2.0",
1372 | "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
1373 | "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
1374 | "dev": true,
1375 | "dependencies": {
1376 | "semver-compare": "^1.0.0"
1377 | }
1378 | },
1379 | "node_modules/postcss": {
1380 | "version": "8.4.33",
1381 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
1382 | "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
1383 | "dev": true,
1384 | "funding": [
1385 | {
1386 | "type": "opencollective",
1387 | "url": "https://opencollective.com/postcss/"
1388 | },
1389 | {
1390 | "type": "tidelift",
1391 | "url": "https://tidelift.com/funding/github/npm/postcss"
1392 | },
1393 | {
1394 | "type": "github",
1395 | "url": "https://github.com/sponsors/ai"
1396 | }
1397 | ],
1398 | "dependencies": {
1399 | "nanoid": "^3.3.7",
1400 | "picocolors": "^1.0.0",
1401 | "source-map-js": "^1.0.2"
1402 | },
1403 | "engines": {
1404 | "node": "^10 || ^12 || >=14"
1405 | }
1406 | },
1407 | "node_modules/proxy-from-env": {
1408 | "version": "1.1.0",
1409 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
1410 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
1411 | },
1412 | "node_modules/readdirp": {
1413 | "version": "3.6.0",
1414 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1415 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1416 | "dev": true,
1417 | "dependencies": {
1418 | "picomatch": "^2.2.1"
1419 | },
1420 | "engines": {
1421 | "node": ">=8.10.0"
1422 | }
1423 | },
1424 | "node_modules/require-directory": {
1425 | "version": "2.1.1",
1426 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1427 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
1428 | "dev": true,
1429 | "engines": {
1430 | "node": ">=0.10.0"
1431 | }
1432 | },
1433 | "node_modules/require-package-name": {
1434 | "version": "2.0.1",
1435 | "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
1436 | "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==",
1437 | "dev": true
1438 | },
1439 | "node_modules/resolve": {
1440 | "version": "1.22.8",
1441 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
1442 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
1443 | "dev": true,
1444 | "dependencies": {
1445 | "is-core-module": "^2.13.0",
1446 | "path-parse": "^1.0.7",
1447 | "supports-preserve-symlinks-flag": "^1.0.0"
1448 | },
1449 | "bin": {
1450 | "resolve": "bin/resolve"
1451 | },
1452 | "funding": {
1453 | "url": "https://github.com/sponsors/ljharb"
1454 | }
1455 | },
1456 | "node_modules/resolve-dir": {
1457 | "version": "1.0.1",
1458 | "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
1459 | "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
1460 | "dev": true,
1461 | "dependencies": {
1462 | "expand-tilde": "^2.0.0",
1463 | "global-modules": "^1.0.0"
1464 | },
1465 | "engines": {
1466 | "node": ">=0.10.0"
1467 | }
1468 | },
1469 | "node_modules/resolve-from": {
1470 | "version": "5.0.0",
1471 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
1472 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
1473 | "dev": true,
1474 | "engines": {
1475 | "node": ">=8"
1476 | }
1477 | },
1478 | "node_modules/safe-buffer": {
1479 | "version": "5.2.1",
1480 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1481 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1482 | "funding": [
1483 | {
1484 | "type": "github",
1485 | "url": "https://github.com/sponsors/feross"
1486 | },
1487 | {
1488 | "type": "patreon",
1489 | "url": "https://www.patreon.com/feross"
1490 | },
1491 | {
1492 | "type": "consulting",
1493 | "url": "https://feross.org/support"
1494 | }
1495 | ]
1496 | },
1497 | "node_modules/semver": {
1498 | "version": "7.5.4",
1499 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
1500 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
1501 | "dependencies": {
1502 | "lru-cache": "^6.0.0"
1503 | },
1504 | "bin": {
1505 | "semver": "bin/semver.js"
1506 | },
1507 | "engines": {
1508 | "node": ">=10"
1509 | }
1510 | },
1511 | "node_modules/semver-compare": {
1512 | "version": "1.0.0",
1513 | "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
1514 | "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
1515 | "dev": true
1516 | },
1517 | "node_modules/source-map-js": {
1518 | "version": "1.0.2",
1519 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
1520 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
1521 | "dev": true,
1522 | "engines": {
1523 | "node": ">=0.10.0"
1524 | }
1525 | },
1526 | "node_modules/sprintf-js": {
1527 | "version": "1.0.3",
1528 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
1529 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
1530 | "dev": true
1531 | },
1532 | "node_modules/string-width": {
1533 | "version": "4.2.3",
1534 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1535 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1536 | "dev": true,
1537 | "dependencies": {
1538 | "emoji-regex": "^8.0.0",
1539 | "is-fullwidth-code-point": "^3.0.0",
1540 | "strip-ansi": "^6.0.1"
1541 | },
1542 | "engines": {
1543 | "node": ">=8"
1544 | }
1545 | },
1546 | "node_modules/strip-ansi": {
1547 | "version": "6.0.1",
1548 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1549 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1550 | "dev": true,
1551 | "dependencies": {
1552 | "ansi-regex": "^5.0.1"
1553 | },
1554 | "engines": {
1555 | "node": ">=8"
1556 | }
1557 | },
1558 | "node_modules/supports-color": {
1559 | "version": "5.5.0",
1560 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1561 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1562 | "dev": true,
1563 | "dependencies": {
1564 | "has-flag": "^3.0.0"
1565 | },
1566 | "engines": {
1567 | "node": ">=4"
1568 | }
1569 | },
1570 | "node_modules/supports-preserve-symlinks-flag": {
1571 | "version": "1.0.0",
1572 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
1573 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
1574 | "dev": true,
1575 | "engines": {
1576 | "node": ">= 0.4"
1577 | },
1578 | "funding": {
1579 | "url": "https://github.com/sponsors/ljharb"
1580 | }
1581 | },
1582 | "node_modules/to-fast-properties": {
1583 | "version": "2.0.0",
1584 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
1585 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
1586 | "dev": true,
1587 | "engines": {
1588 | "node": ">=4"
1589 | }
1590 | },
1591 | "node_modules/to-regex-range": {
1592 | "version": "5.0.1",
1593 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1594 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1595 | "dev": true,
1596 | "dependencies": {
1597 | "is-number": "^7.0.0"
1598 | },
1599 | "engines": {
1600 | "node": ">=8.0"
1601 | }
1602 | },
1603 | "node_modules/which": {
1604 | "version": "1.3.1",
1605 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1606 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1607 | "dev": true,
1608 | "dependencies": {
1609 | "isexe": "^2.0.0"
1610 | },
1611 | "bin": {
1612 | "which": "bin/which"
1613 | }
1614 | },
1615 | "node_modules/wrap-ansi": {
1616 | "version": "7.0.0",
1617 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1618 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1619 | "dev": true,
1620 | "dependencies": {
1621 | "ansi-styles": "^4.0.0",
1622 | "string-width": "^4.1.0",
1623 | "strip-ansi": "^6.0.0"
1624 | },
1625 | "engines": {
1626 | "node": ">=10"
1627 | },
1628 | "funding": {
1629 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1630 | }
1631 | },
1632 | "node_modules/wrap-ansi/node_modules/ansi-styles": {
1633 | "version": "4.3.0",
1634 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1635 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1636 | "dev": true,
1637 | "dependencies": {
1638 | "color-convert": "^2.0.1"
1639 | },
1640 | "engines": {
1641 | "node": ">=8"
1642 | },
1643 | "funding": {
1644 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1645 | }
1646 | },
1647 | "node_modules/wrap-ansi/node_modules/color-convert": {
1648 | "version": "2.0.1",
1649 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1650 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1651 | "dev": true,
1652 | "dependencies": {
1653 | "color-name": "~1.1.4"
1654 | },
1655 | "engines": {
1656 | "node": ">=7.0.0"
1657 | }
1658 | },
1659 | "node_modules/wrap-ansi/node_modules/color-name": {
1660 | "version": "1.1.4",
1661 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1662 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1663 | "dev": true
1664 | },
1665 | "node_modules/y18n": {
1666 | "version": "5.0.8",
1667 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
1668 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
1669 | "dev": true,
1670 | "engines": {
1671 | "node": ">=10"
1672 | }
1673 | },
1674 | "node_modules/yallist": {
1675 | "version": "4.0.0",
1676 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1677 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
1678 | },
1679 | "node_modules/yaml": {
1680 | "version": "1.10.2",
1681 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
1682 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
1683 | "dev": true,
1684 | "engines": {
1685 | "node": ">= 6"
1686 | }
1687 | },
1688 | "node_modules/yargs": {
1689 | "version": "16.2.0",
1690 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
1691 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
1692 | "dev": true,
1693 | "dependencies": {
1694 | "cliui": "^7.0.2",
1695 | "escalade": "^3.1.1",
1696 | "get-caller-file": "^2.0.5",
1697 | "require-directory": "^2.1.1",
1698 | "string-width": "^4.2.0",
1699 | "y18n": "^5.0.5",
1700 | "yargs-parser": "^20.2.2"
1701 | },
1702 | "engines": {
1703 | "node": ">=10"
1704 | }
1705 | },
1706 | "node_modules/yargs-parser": {
1707 | "version": "20.2.9",
1708 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
1709 | "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
1710 | "dev": true,
1711 | "engines": {
1712 | "node": ">=10"
1713 | }
1714 | }
1715 | },
1716 | "dependencies": {
1717 | "@babel/code-frame": {
1718 | "version": "7.23.5",
1719 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
1720 | "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
1721 | "dev": true,
1722 | "requires": {
1723 | "@babel/highlight": "^7.23.4",
1724 | "chalk": "^2.4.2"
1725 | }
1726 | },
1727 | "@babel/generator": {
1728 | "version": "7.23.6",
1729 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
1730 | "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
1731 | "dev": true,
1732 | "requires": {
1733 | "@babel/types": "^7.23.6",
1734 | "@jridgewell/gen-mapping": "^0.3.2",
1735 | "@jridgewell/trace-mapping": "^0.3.17",
1736 | "jsesc": "^2.5.1"
1737 | }
1738 | },
1739 | "@babel/helper-environment-visitor": {
1740 | "version": "7.22.20",
1741 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
1742 | "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
1743 | "dev": true
1744 | },
1745 | "@babel/helper-function-name": {
1746 | "version": "7.23.0",
1747 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
1748 | "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
1749 | "dev": true,
1750 | "requires": {
1751 | "@babel/template": "^7.22.15",
1752 | "@babel/types": "^7.23.0"
1753 | }
1754 | },
1755 | "@babel/helper-hoist-variables": {
1756 | "version": "7.22.5",
1757 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
1758 | "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
1759 | "dev": true,
1760 | "requires": {
1761 | "@babel/types": "^7.22.5"
1762 | }
1763 | },
1764 | "@babel/helper-split-export-declaration": {
1765 | "version": "7.22.6",
1766 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
1767 | "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
1768 | "dev": true,
1769 | "requires": {
1770 | "@babel/types": "^7.22.5"
1771 | }
1772 | },
1773 | "@babel/helper-string-parser": {
1774 | "version": "7.23.4",
1775 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
1776 | "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
1777 | "dev": true
1778 | },
1779 | "@babel/helper-validator-identifier": {
1780 | "version": "7.22.20",
1781 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
1782 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
1783 | "dev": true
1784 | },
1785 | "@babel/highlight": {
1786 | "version": "7.23.4",
1787 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
1788 | "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
1789 | "dev": true,
1790 | "requires": {
1791 | "@babel/helper-validator-identifier": "^7.22.20",
1792 | "chalk": "^2.4.2",
1793 | "js-tokens": "^4.0.0"
1794 | }
1795 | },
1796 | "@babel/parser": {
1797 | "version": "7.23.6",
1798 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
1799 | "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
1800 | "dev": true
1801 | },
1802 | "@babel/template": {
1803 | "version": "7.22.15",
1804 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
1805 | "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
1806 | "dev": true,
1807 | "requires": {
1808 | "@babel/code-frame": "^7.22.13",
1809 | "@babel/parser": "^7.22.15",
1810 | "@babel/types": "^7.22.15"
1811 | }
1812 | },
1813 | "@babel/traverse": {
1814 | "version": "7.23.7",
1815 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
1816 | "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
1817 | "dev": true,
1818 | "requires": {
1819 | "@babel/code-frame": "^7.23.5",
1820 | "@babel/generator": "^7.23.6",
1821 | "@babel/helper-environment-visitor": "^7.22.20",
1822 | "@babel/helper-function-name": "^7.23.0",
1823 | "@babel/helper-hoist-variables": "^7.22.5",
1824 | "@babel/helper-split-export-declaration": "^7.22.6",
1825 | "@babel/parser": "^7.23.6",
1826 | "@babel/types": "^7.23.6",
1827 | "debug": "^4.3.1",
1828 | "globals": "^11.1.0"
1829 | }
1830 | },
1831 | "@babel/types": {
1832 | "version": "7.23.6",
1833 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
1834 | "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
1835 | "dev": true,
1836 | "requires": {
1837 | "@babel/helper-string-parser": "^7.23.4",
1838 | "@babel/helper-validator-identifier": "^7.22.20",
1839 | "to-fast-properties": "^2.0.0"
1840 | }
1841 | },
1842 | "@jridgewell/gen-mapping": {
1843 | "version": "0.3.3",
1844 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
1845 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
1846 | "dev": true,
1847 | "requires": {
1848 | "@jridgewell/set-array": "^1.0.1",
1849 | "@jridgewell/sourcemap-codec": "^1.4.10",
1850 | "@jridgewell/trace-mapping": "^0.3.9"
1851 | }
1852 | },
1853 | "@jridgewell/resolve-uri": {
1854 | "version": "3.1.1",
1855 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
1856 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
1857 | "dev": true
1858 | },
1859 | "@jridgewell/set-array": {
1860 | "version": "1.1.2",
1861 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
1862 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
1863 | "dev": true
1864 | },
1865 | "@jridgewell/sourcemap-codec": {
1866 | "version": "1.4.15",
1867 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
1868 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
1869 | "dev": true
1870 | },
1871 | "@jridgewell/trace-mapping": {
1872 | "version": "0.3.22",
1873 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
1874 | "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
1875 | "dev": true,
1876 | "requires": {
1877 | "@jridgewell/resolve-uri": "^3.1.0",
1878 | "@jridgewell/sourcemap-codec": "^1.4.14"
1879 | }
1880 | },
1881 | "@types/minimatch": {
1882 | "version": "3.0.5",
1883 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
1884 | "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
1885 | "dev": true
1886 | },
1887 | "@types/parse-json": {
1888 | "version": "4.0.2",
1889 | "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
1890 | "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
1891 | "dev": true
1892 | },
1893 | "@vue/compiler-core": {
1894 | "version": "3.4.15",
1895 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz",
1896 | "integrity": "sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==",
1897 | "dev": true,
1898 | "requires": {
1899 | "@babel/parser": "^7.23.6",
1900 | "@vue/shared": "3.4.15",
1901 | "entities": "^4.5.0",
1902 | "estree-walker": "^2.0.2",
1903 | "source-map-js": "^1.0.2"
1904 | }
1905 | },
1906 | "@vue/compiler-dom": {
1907 | "version": "3.4.15",
1908 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz",
1909 | "integrity": "sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==",
1910 | "dev": true,
1911 | "requires": {
1912 | "@vue/compiler-core": "3.4.15",
1913 | "@vue/shared": "3.4.15"
1914 | }
1915 | },
1916 | "@vue/compiler-sfc": {
1917 | "version": "3.4.15",
1918 | "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz",
1919 | "integrity": "sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==",
1920 | "dev": true,
1921 | "requires": {
1922 | "@babel/parser": "^7.23.6",
1923 | "@vue/compiler-core": "3.4.15",
1924 | "@vue/compiler-dom": "3.4.15",
1925 | "@vue/compiler-ssr": "3.4.15",
1926 | "@vue/shared": "3.4.15",
1927 | "estree-walker": "^2.0.2",
1928 | "magic-string": "^0.30.5",
1929 | "postcss": "^8.4.33",
1930 | "source-map-js": "^1.0.2"
1931 | }
1932 | },
1933 | "@vue/compiler-ssr": {
1934 | "version": "3.4.15",
1935 | "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz",
1936 | "integrity": "sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==",
1937 | "dev": true,
1938 | "requires": {
1939 | "@vue/compiler-dom": "3.4.15",
1940 | "@vue/shared": "3.4.15"
1941 | }
1942 | },
1943 | "@vue/shared": {
1944 | "version": "3.4.15",
1945 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz",
1946 | "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==",
1947 | "dev": true
1948 | },
1949 | "ansi-regex": {
1950 | "version": "5.0.1",
1951 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1952 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1953 | "dev": true
1954 | },
1955 | "ansi-styles": {
1956 | "version": "3.2.1",
1957 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
1958 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
1959 | "dev": true,
1960 | "requires": {
1961 | "color-convert": "^1.9.0"
1962 | }
1963 | },
1964 | "argparse": {
1965 | "version": "1.0.10",
1966 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
1967 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
1968 | "dev": true,
1969 | "requires": {
1970 | "sprintf-js": "~1.0.2"
1971 | }
1972 | },
1973 | "array-differ": {
1974 | "version": "3.0.0",
1975 | "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
1976 | "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
1977 | "dev": true
1978 | },
1979 | "array-union": {
1980 | "version": "2.1.0",
1981 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
1982 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
1983 | "dev": true
1984 | },
1985 | "arrify": {
1986 | "version": "2.0.1",
1987 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
1988 | "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
1989 | "dev": true
1990 | },
1991 | "asn1.js": {
1992 | "version": "4.10.1",
1993 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
1994 | "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
1995 | "requires": {
1996 | "bn.js": "^4.0.0",
1997 | "inherits": "^2.0.1",
1998 | "minimalistic-assert": "^1.0.0"
1999 | }
2000 | },
2001 | "asynckit": {
2002 | "version": "0.4.0",
2003 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
2004 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
2005 | },
2006 | "axios": {
2007 | "version": "1.6.5",
2008 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz",
2009 | "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==",
2010 | "requires": {
2011 | "follow-redirects": "^1.15.4",
2012 | "form-data": "^4.0.0",
2013 | "proxy-from-env": "^1.1.0"
2014 | }
2015 | },
2016 | "balanced-match": {
2017 | "version": "1.0.2",
2018 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
2019 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
2020 | "dev": true
2021 | },
2022 | "base64url": {
2023 | "version": "3.0.1",
2024 | "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
2025 | "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="
2026 | },
2027 | "bn.js": {
2028 | "version": "4.12.0",
2029 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
2030 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
2031 | },
2032 | "brace-expansion": {
2033 | "version": "2.0.1",
2034 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
2035 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
2036 | "dev": true,
2037 | "requires": {
2038 | "balanced-match": "^1.0.0"
2039 | }
2040 | },
2041 | "braces": {
2042 | "version": "3.0.2",
2043 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
2044 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
2045 | "dev": true,
2046 | "requires": {
2047 | "fill-range": "^7.0.1"
2048 | }
2049 | },
2050 | "brorand": {
2051 | "version": "1.1.0",
2052 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
2053 | "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w=="
2054 | },
2055 | "buffer-equal-constant-time": {
2056 | "version": "1.0.1",
2057 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
2058 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
2059 | },
2060 | "callsite": {
2061 | "version": "1.0.0",
2062 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
2063 | "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==",
2064 | "dev": true
2065 | },
2066 | "callsites": {
2067 | "version": "3.1.0",
2068 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
2069 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
2070 | "dev": true
2071 | },
2072 | "camelcase": {
2073 | "version": "6.3.0",
2074 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
2075 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
2076 | "dev": true
2077 | },
2078 | "chalk": {
2079 | "version": "2.4.2",
2080 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
2081 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
2082 | "dev": true,
2083 | "requires": {
2084 | "ansi-styles": "^3.2.1",
2085 | "escape-string-regexp": "^1.0.5",
2086 | "supports-color": "^5.3.0"
2087 | }
2088 | },
2089 | "cliui": {
2090 | "version": "7.0.4",
2091 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
2092 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
2093 | "dev": true,
2094 | "requires": {
2095 | "string-width": "^4.2.0",
2096 | "strip-ansi": "^6.0.0",
2097 | "wrap-ansi": "^7.0.0"
2098 | }
2099 | },
2100 | "color-convert": {
2101 | "version": "1.9.3",
2102 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
2103 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
2104 | "dev": true,
2105 | "requires": {
2106 | "color-name": "1.1.3"
2107 | }
2108 | },
2109 | "color-name": {
2110 | "version": "1.1.3",
2111 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
2112 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
2113 | "dev": true
2114 | },
2115 | "combined-stream": {
2116 | "version": "1.0.8",
2117 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
2118 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
2119 | "requires": {
2120 | "delayed-stream": "~1.0.0"
2121 | }
2122 | },
2123 | "concat-map": {
2124 | "version": "0.0.1",
2125 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
2126 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
2127 | "dev": true
2128 | },
2129 | "cookie": {
2130 | "version": "0.3.1",
2131 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
2132 | "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw=="
2133 | },
2134 | "cosmiconfig": {
2135 | "version": "7.1.0",
2136 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
2137 | "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
2138 | "dev": true,
2139 | "requires": {
2140 | "@types/parse-json": "^4.0.0",
2141 | "import-fresh": "^3.2.1",
2142 | "parse-json": "^5.0.0",
2143 | "path-type": "^4.0.0",
2144 | "yaml": "^1.10.0"
2145 | }
2146 | },
2147 | "debug": {
2148 | "version": "4.3.4",
2149 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
2150 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
2151 | "dev": true,
2152 | "requires": {
2153 | "ms": "2.1.2"
2154 | }
2155 | },
2156 | "delayed-stream": {
2157 | "version": "1.0.0",
2158 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
2159 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
2160 | },
2161 | "depcheck": {
2162 | "version": "1.4.7",
2163 | "resolved": "https://registry.npmjs.org/depcheck/-/depcheck-1.4.7.tgz",
2164 | "integrity": "sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==",
2165 | "dev": true,
2166 | "requires": {
2167 | "@babel/parser": "^7.23.0",
2168 | "@babel/traverse": "^7.23.2",
2169 | "@vue/compiler-sfc": "^3.3.4",
2170 | "callsite": "^1.0.0",
2171 | "camelcase": "^6.3.0",
2172 | "cosmiconfig": "^7.1.0",
2173 | "debug": "^4.3.4",
2174 | "deps-regex": "^0.2.0",
2175 | "findup-sync": "^5.0.0",
2176 | "ignore": "^5.2.4",
2177 | "is-core-module": "^2.12.0",
2178 | "js-yaml": "^3.14.1",
2179 | "json5": "^2.2.3",
2180 | "lodash": "^4.17.21",
2181 | "minimatch": "^7.4.6",
2182 | "multimatch": "^5.0.0",
2183 | "please-upgrade-node": "^3.2.0",
2184 | "readdirp": "^3.6.0",
2185 | "require-package-name": "^2.0.1",
2186 | "resolve": "^1.22.3",
2187 | "resolve-from": "^5.0.0",
2188 | "semver": "^7.5.4",
2189 | "yargs": "^16.2.0"
2190 | }
2191 | },
2192 | "deps-regex": {
2193 | "version": "0.2.0",
2194 | "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.2.0.tgz",
2195 | "integrity": "sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==",
2196 | "dev": true
2197 | },
2198 | "detect-file": {
2199 | "version": "1.0.0",
2200 | "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
2201 | "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
2202 | "dev": true
2203 | },
2204 | "ecdsa-sig-formatter": {
2205 | "version": "1.0.11",
2206 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
2207 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
2208 | "requires": {
2209 | "safe-buffer": "^5.0.1"
2210 | }
2211 | },
2212 | "elliptic": {
2213 | "version": "6.5.4",
2214 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
2215 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
2216 | "requires": {
2217 | "bn.js": "^4.11.9",
2218 | "brorand": "^1.1.0",
2219 | "hash.js": "^1.0.0",
2220 | "hmac-drbg": "^1.0.1",
2221 | "inherits": "^2.0.4",
2222 | "minimalistic-assert": "^1.0.1",
2223 | "minimalistic-crypto-utils": "^1.0.1"
2224 | }
2225 | },
2226 | "emoji-regex": {
2227 | "version": "8.0.0",
2228 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2229 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2230 | "dev": true
2231 | },
2232 | "entities": {
2233 | "version": "4.5.0",
2234 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
2235 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
2236 | "dev": true
2237 | },
2238 | "error-ex": {
2239 | "version": "1.3.2",
2240 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
2241 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
2242 | "dev": true,
2243 | "requires": {
2244 | "is-arrayish": "^0.2.1"
2245 | }
2246 | },
2247 | "escalade": {
2248 | "version": "3.1.1",
2249 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
2250 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
2251 | "dev": true
2252 | },
2253 | "escape-string-regexp": {
2254 | "version": "1.0.5",
2255 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
2256 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
2257 | "dev": true
2258 | },
2259 | "esprima": {
2260 | "version": "4.0.1",
2261 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
2262 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
2263 | "dev": true
2264 | },
2265 | "estree-walker": {
2266 | "version": "2.0.2",
2267 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
2268 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
2269 | "dev": true
2270 | },
2271 | "expand-tilde": {
2272 | "version": "2.0.2",
2273 | "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
2274 | "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
2275 | "dev": true,
2276 | "requires": {
2277 | "homedir-polyfill": "^1.0.1"
2278 | }
2279 | },
2280 | "fill-range": {
2281 | "version": "7.0.1",
2282 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
2283 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
2284 | "dev": true,
2285 | "requires": {
2286 | "to-regex-range": "^5.0.1"
2287 | }
2288 | },
2289 | "findup-sync": {
2290 | "version": "5.0.0",
2291 | "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
2292 | "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
2293 | "dev": true,
2294 | "requires": {
2295 | "detect-file": "^1.0.0",
2296 | "is-glob": "^4.0.3",
2297 | "micromatch": "^4.0.4",
2298 | "resolve-dir": "^1.0.1"
2299 | }
2300 | },
2301 | "follow-redirects": {
2302 | "version": "1.15.5",
2303 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
2304 | "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw=="
2305 | },
2306 | "form-data": {
2307 | "version": "4.0.0",
2308 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
2309 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
2310 | "requires": {
2311 | "asynckit": "^0.4.0",
2312 | "combined-stream": "^1.0.8",
2313 | "mime-types": "^2.1.12"
2314 | }
2315 | },
2316 | "function-bind": {
2317 | "version": "1.1.2",
2318 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
2319 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
2320 | "dev": true
2321 | },
2322 | "get-caller-file": {
2323 | "version": "2.0.5",
2324 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
2325 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
2326 | "dev": true
2327 | },
2328 | "global-modules": {
2329 | "version": "1.0.0",
2330 | "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
2331 | "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
2332 | "dev": true,
2333 | "requires": {
2334 | "global-prefix": "^1.0.1",
2335 | "is-windows": "^1.0.1",
2336 | "resolve-dir": "^1.0.0"
2337 | }
2338 | },
2339 | "global-prefix": {
2340 | "version": "1.0.2",
2341 | "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
2342 | "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
2343 | "dev": true,
2344 | "requires": {
2345 | "expand-tilde": "^2.0.2",
2346 | "homedir-polyfill": "^1.0.1",
2347 | "ini": "^1.3.4",
2348 | "is-windows": "^1.0.1",
2349 | "which": "^1.2.14"
2350 | }
2351 | },
2352 | "globals": {
2353 | "version": "11.12.0",
2354 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
2355 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
2356 | "dev": true
2357 | },
2358 | "has-flag": {
2359 | "version": "3.0.0",
2360 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
2361 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
2362 | "dev": true
2363 | },
2364 | "hash.js": {
2365 | "version": "1.1.7",
2366 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
2367 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
2368 | "requires": {
2369 | "inherits": "^2.0.3",
2370 | "minimalistic-assert": "^1.0.1"
2371 | }
2372 | },
2373 | "hasown": {
2374 | "version": "2.0.0",
2375 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
2376 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
2377 | "dev": true,
2378 | "requires": {
2379 | "function-bind": "^1.1.2"
2380 | }
2381 | },
2382 | "hmac-drbg": {
2383 | "version": "1.0.1",
2384 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
2385 | "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
2386 | "requires": {
2387 | "hash.js": "^1.0.3",
2388 | "minimalistic-assert": "^1.0.0",
2389 | "minimalistic-crypto-utils": "^1.0.1"
2390 | }
2391 | },
2392 | "homedir-polyfill": {
2393 | "version": "1.0.3",
2394 | "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
2395 | "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
2396 | "dev": true,
2397 | "requires": {
2398 | "parse-passwd": "^1.0.0"
2399 | }
2400 | },
2401 | "ignore": {
2402 | "version": "5.3.0",
2403 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
2404 | "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==",
2405 | "dev": true
2406 | },
2407 | "import-fresh": {
2408 | "version": "3.3.0",
2409 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
2410 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
2411 | "dev": true,
2412 | "requires": {
2413 | "parent-module": "^1.0.0",
2414 | "resolve-from": "^4.0.0"
2415 | },
2416 | "dependencies": {
2417 | "resolve-from": {
2418 | "version": "4.0.0",
2419 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
2420 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
2421 | "dev": true
2422 | }
2423 | }
2424 | },
2425 | "inherits": {
2426 | "version": "2.0.4",
2427 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
2428 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
2429 | },
2430 | "ini": {
2431 | "version": "1.3.8",
2432 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
2433 | "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
2434 | "dev": true
2435 | },
2436 | "is-arrayish": {
2437 | "version": "0.2.1",
2438 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
2439 | "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
2440 | "dev": true
2441 | },
2442 | "is-core-module": {
2443 | "version": "2.13.1",
2444 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
2445 | "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
2446 | "dev": true,
2447 | "requires": {
2448 | "hasown": "^2.0.0"
2449 | }
2450 | },
2451 | "is-extglob": {
2452 | "version": "2.1.1",
2453 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
2454 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
2455 | "dev": true
2456 | },
2457 | "is-fullwidth-code-point": {
2458 | "version": "3.0.0",
2459 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
2460 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
2461 | "dev": true
2462 | },
2463 | "is-glob": {
2464 | "version": "4.0.3",
2465 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
2466 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
2467 | "dev": true,
2468 | "requires": {
2469 | "is-extglob": "^2.1.1"
2470 | }
2471 | },
2472 | "is-number": {
2473 | "version": "7.0.0",
2474 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
2475 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
2476 | "dev": true
2477 | },
2478 | "is-windows": {
2479 | "version": "1.0.2",
2480 | "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
2481 | "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
2482 | "dev": true
2483 | },
2484 | "isexe": {
2485 | "version": "2.0.0",
2486 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
2487 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
2488 | "dev": true
2489 | },
2490 | "js-tokens": {
2491 | "version": "4.0.0",
2492 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
2493 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
2494 | "dev": true
2495 | },
2496 | "js-yaml": {
2497 | "version": "3.14.1",
2498 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
2499 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
2500 | "dev": true,
2501 | "requires": {
2502 | "argparse": "^1.0.7",
2503 | "esprima": "^4.0.0"
2504 | }
2505 | },
2506 | "jsesc": {
2507 | "version": "2.5.2",
2508 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
2509 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
2510 | "dev": true
2511 | },
2512 | "json-parse-even-better-errors": {
2513 | "version": "2.3.1",
2514 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
2515 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
2516 | "dev": true
2517 | },
2518 | "json5": {
2519 | "version": "2.2.3",
2520 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
2521 | "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
2522 | "dev": true
2523 | },
2524 | "jsonwebtoken": {
2525 | "version": "9.0.2",
2526 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
2527 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
2528 | "requires": {
2529 | "jws": "^3.2.2",
2530 | "lodash.includes": "^4.3.0",
2531 | "lodash.isboolean": "^3.0.3",
2532 | "lodash.isinteger": "^4.0.4",
2533 | "lodash.isnumber": "^3.0.3",
2534 | "lodash.isplainobject": "^4.0.6",
2535 | "lodash.isstring": "^4.0.1",
2536 | "lodash.once": "^4.0.0",
2537 | "ms": "^2.1.1",
2538 | "semver": "^7.5.4"
2539 | }
2540 | },
2541 | "jwa": {
2542 | "version": "1.4.1",
2543 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
2544 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
2545 | "requires": {
2546 | "buffer-equal-constant-time": "1.0.1",
2547 | "ecdsa-sig-formatter": "1.0.11",
2548 | "safe-buffer": "^5.0.1"
2549 | }
2550 | },
2551 | "jwk-to-pem": {
2552 | "version": "1.2.6",
2553 | "resolved": "https://registry.npmjs.org/jwk-to-pem/-/jwk-to-pem-1.2.6.tgz",
2554 | "integrity": "sha512-Ipnj4HJk49KJ6j8u6niB37f8waRf+9uDpJlnk9QRJbH2AIII2w59VoajS5s2V0MYfIS5s+Hys9G6dspJmLn95Q==",
2555 | "requires": {
2556 | "asn1.js": "^4.5.2",
2557 | "elliptic": "^6.2.3",
2558 | "safe-buffer": "^5.0.1"
2559 | }
2560 | },
2561 | "jws": {
2562 | "version": "3.2.2",
2563 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
2564 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
2565 | "requires": {
2566 | "jwa": "^1.4.1",
2567 | "safe-buffer": "^5.0.1"
2568 | }
2569 | },
2570 | "lines-and-columns": {
2571 | "version": "1.2.4",
2572 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
2573 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
2574 | "dev": true
2575 | },
2576 | "lodash": {
2577 | "version": "4.17.21",
2578 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
2579 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
2580 | "dev": true
2581 | },
2582 | "lodash.includes": {
2583 | "version": "4.3.0",
2584 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
2585 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
2586 | },
2587 | "lodash.isboolean": {
2588 | "version": "3.0.3",
2589 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
2590 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
2591 | },
2592 | "lodash.isinteger": {
2593 | "version": "4.0.4",
2594 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
2595 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
2596 | },
2597 | "lodash.isnumber": {
2598 | "version": "3.0.3",
2599 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
2600 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
2601 | },
2602 | "lodash.isplainobject": {
2603 | "version": "4.0.6",
2604 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
2605 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
2606 | },
2607 | "lodash.isstring": {
2608 | "version": "4.0.1",
2609 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
2610 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
2611 | },
2612 | "lodash.once": {
2613 | "version": "4.1.1",
2614 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
2615 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
2616 | },
2617 | "lru-cache": {
2618 | "version": "6.0.0",
2619 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
2620 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
2621 | "requires": {
2622 | "yallist": "^4.0.0"
2623 | }
2624 | },
2625 | "magic-string": {
2626 | "version": "0.30.5",
2627 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
2628 | "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
2629 | "dev": true,
2630 | "requires": {
2631 | "@jridgewell/sourcemap-codec": "^1.4.15"
2632 | }
2633 | },
2634 | "micromatch": {
2635 | "version": "4.0.5",
2636 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
2637 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
2638 | "dev": true,
2639 | "requires": {
2640 | "braces": "^3.0.2",
2641 | "picomatch": "^2.3.1"
2642 | }
2643 | },
2644 | "mime-db": {
2645 | "version": "1.52.0",
2646 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
2647 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
2648 | },
2649 | "mime-types": {
2650 | "version": "2.1.35",
2651 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
2652 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
2653 | "requires": {
2654 | "mime-db": "1.52.0"
2655 | }
2656 | },
2657 | "minimalistic-assert": {
2658 | "version": "1.0.1",
2659 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
2660 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
2661 | },
2662 | "minimalistic-crypto-utils": {
2663 | "version": "1.0.1",
2664 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
2665 | "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="
2666 | },
2667 | "minimatch": {
2668 | "version": "7.4.6",
2669 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz",
2670 | "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==",
2671 | "dev": true,
2672 | "requires": {
2673 | "brace-expansion": "^2.0.1"
2674 | }
2675 | },
2676 | "ms": {
2677 | "version": "2.1.2",
2678 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
2679 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
2680 | },
2681 | "multimatch": {
2682 | "version": "5.0.0",
2683 | "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz",
2684 | "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==",
2685 | "dev": true,
2686 | "requires": {
2687 | "@types/minimatch": "^3.0.3",
2688 | "array-differ": "^3.0.0",
2689 | "array-union": "^2.1.0",
2690 | "arrify": "^2.0.1",
2691 | "minimatch": "^3.0.4"
2692 | },
2693 | "dependencies": {
2694 | "brace-expansion": {
2695 | "version": "1.1.11",
2696 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
2697 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
2698 | "dev": true,
2699 | "requires": {
2700 | "balanced-match": "^1.0.0",
2701 | "concat-map": "0.0.1"
2702 | }
2703 | },
2704 | "minimatch": {
2705 | "version": "3.1.2",
2706 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
2707 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
2708 | "dev": true,
2709 | "requires": {
2710 | "brace-expansion": "^1.1.7"
2711 | }
2712 | }
2713 | }
2714 | },
2715 | "nanoid": {
2716 | "version": "3.3.7",
2717 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
2718 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
2719 | "dev": true
2720 | },
2721 | "parent-module": {
2722 | "version": "1.0.1",
2723 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
2724 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
2725 | "dev": true,
2726 | "requires": {
2727 | "callsites": "^3.0.0"
2728 | }
2729 | },
2730 | "parse-json": {
2731 | "version": "5.2.0",
2732 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
2733 | "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
2734 | "dev": true,
2735 | "requires": {
2736 | "@babel/code-frame": "^7.0.0",
2737 | "error-ex": "^1.3.1",
2738 | "json-parse-even-better-errors": "^2.3.0",
2739 | "lines-and-columns": "^1.1.6"
2740 | }
2741 | },
2742 | "parse-passwd": {
2743 | "version": "1.0.0",
2744 | "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
2745 | "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
2746 | "dev": true
2747 | },
2748 | "path-parse": {
2749 | "version": "1.0.7",
2750 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
2751 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
2752 | "dev": true
2753 | },
2754 | "path-type": {
2755 | "version": "4.0.0",
2756 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
2757 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
2758 | "dev": true
2759 | },
2760 | "picocolors": {
2761 | "version": "1.0.0",
2762 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
2763 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
2764 | "dev": true
2765 | },
2766 | "picomatch": {
2767 | "version": "2.3.1",
2768 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
2769 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
2770 | "dev": true
2771 | },
2772 | "please-upgrade-node": {
2773 | "version": "3.2.0",
2774 | "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
2775 | "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
2776 | "dev": true,
2777 | "requires": {
2778 | "semver-compare": "^1.0.0"
2779 | }
2780 | },
2781 | "postcss": {
2782 | "version": "8.4.33",
2783 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
2784 | "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
2785 | "dev": true,
2786 | "requires": {
2787 | "nanoid": "^3.3.7",
2788 | "picocolors": "^1.0.0",
2789 | "source-map-js": "^1.0.2"
2790 | }
2791 | },
2792 | "proxy-from-env": {
2793 | "version": "1.1.0",
2794 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
2795 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
2796 | },
2797 | "readdirp": {
2798 | "version": "3.6.0",
2799 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
2800 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
2801 | "dev": true,
2802 | "requires": {
2803 | "picomatch": "^2.2.1"
2804 | }
2805 | },
2806 | "require-directory": {
2807 | "version": "2.1.1",
2808 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
2809 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
2810 | "dev": true
2811 | },
2812 | "require-package-name": {
2813 | "version": "2.0.1",
2814 | "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
2815 | "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==",
2816 | "dev": true
2817 | },
2818 | "resolve": {
2819 | "version": "1.22.8",
2820 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
2821 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
2822 | "dev": true,
2823 | "requires": {
2824 | "is-core-module": "^2.13.0",
2825 | "path-parse": "^1.0.7",
2826 | "supports-preserve-symlinks-flag": "^1.0.0"
2827 | }
2828 | },
2829 | "resolve-dir": {
2830 | "version": "1.0.1",
2831 | "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
2832 | "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
2833 | "dev": true,
2834 | "requires": {
2835 | "expand-tilde": "^2.0.0",
2836 | "global-modules": "^1.0.0"
2837 | }
2838 | },
2839 | "resolve-from": {
2840 | "version": "5.0.0",
2841 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
2842 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
2843 | "dev": true
2844 | },
2845 | "safe-buffer": {
2846 | "version": "5.2.1",
2847 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
2848 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
2849 | },
2850 | "semver": {
2851 | "version": "7.5.4",
2852 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
2853 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
2854 | "requires": {
2855 | "lru-cache": "^6.0.0"
2856 | }
2857 | },
2858 | "semver-compare": {
2859 | "version": "1.0.0",
2860 | "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
2861 | "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
2862 | "dev": true
2863 | },
2864 | "source-map-js": {
2865 | "version": "1.0.2",
2866 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
2867 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
2868 | "dev": true
2869 | },
2870 | "sprintf-js": {
2871 | "version": "1.0.3",
2872 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
2873 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
2874 | "dev": true
2875 | },
2876 | "string-width": {
2877 | "version": "4.2.3",
2878 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2879 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2880 | "dev": true,
2881 | "requires": {
2882 | "emoji-regex": "^8.0.0",
2883 | "is-fullwidth-code-point": "^3.0.0",
2884 | "strip-ansi": "^6.0.1"
2885 | }
2886 | },
2887 | "strip-ansi": {
2888 | "version": "6.0.1",
2889 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2890 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2891 | "dev": true,
2892 | "requires": {
2893 | "ansi-regex": "^5.0.1"
2894 | }
2895 | },
2896 | "supports-color": {
2897 | "version": "5.5.0",
2898 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
2899 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
2900 | "dev": true,
2901 | "requires": {
2902 | "has-flag": "^3.0.0"
2903 | }
2904 | },
2905 | "supports-preserve-symlinks-flag": {
2906 | "version": "1.0.0",
2907 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
2908 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
2909 | "dev": true
2910 | },
2911 | "to-fast-properties": {
2912 | "version": "2.0.0",
2913 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
2914 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
2915 | "dev": true
2916 | },
2917 | "to-regex-range": {
2918 | "version": "5.0.1",
2919 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2920 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2921 | "dev": true,
2922 | "requires": {
2923 | "is-number": "^7.0.0"
2924 | }
2925 | },
2926 | "which": {
2927 | "version": "1.3.1",
2928 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
2929 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
2930 | "dev": true,
2931 | "requires": {
2932 | "isexe": "^2.0.0"
2933 | }
2934 | },
2935 | "wrap-ansi": {
2936 | "version": "7.0.0",
2937 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2938 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2939 | "dev": true,
2940 | "requires": {
2941 | "ansi-styles": "^4.0.0",
2942 | "string-width": "^4.1.0",
2943 | "strip-ansi": "^6.0.0"
2944 | },
2945 | "dependencies": {
2946 | "ansi-styles": {
2947 | "version": "4.3.0",
2948 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2949 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2950 | "dev": true,
2951 | "requires": {
2952 | "color-convert": "^2.0.1"
2953 | }
2954 | },
2955 | "color-convert": {
2956 | "version": "2.0.1",
2957 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
2958 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
2959 | "dev": true,
2960 | "requires": {
2961 | "color-name": "~1.1.4"
2962 | }
2963 | },
2964 | "color-name": {
2965 | "version": "1.1.4",
2966 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
2967 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
2968 | "dev": true
2969 | }
2970 | }
2971 | },
2972 | "y18n": {
2973 | "version": "5.0.8",
2974 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
2975 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
2976 | "dev": true
2977 | },
2978 | "yallist": {
2979 | "version": "4.0.0",
2980 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
2981 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
2982 | },
2983 | "yaml": {
2984 | "version": "1.10.2",
2985 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
2986 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
2987 | "dev": true
2988 | },
2989 | "yargs": {
2990 | "version": "16.2.0",
2991 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
2992 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
2993 | "dev": true,
2994 | "requires": {
2995 | "cliui": "^7.0.2",
2996 | "escalade": "^3.1.1",
2997 | "get-caller-file": "^2.0.5",
2998 | "require-directory": "^2.1.1",
2999 | "string-width": "^4.2.0",
3000 | "y18n": "^5.0.5",
3001 | "yargs-parser": "^20.2.2"
3002 | }
3003 | },
3004 | "yargs-parser": {
3005 | "version": "20.2.9",
3006 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
3007 | "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
3008 | "dev": true
3009 | }
3010 | }
3011 | }
3012 |
--------------------------------------------------------------------------------